How to quit script when Telebot sees a new message - python

I have two python scripts which I run using a batch script. Once one script is executed, the next script starts. I need one of the scripts, the Telebot script, to quit after recording a message in a .json file. Unfortunately, while the message does get recorded, I am having trouble quitting the script, meaning my second python file is not being executed.
import telebot
import json
import os
import sys
import time
with open('JSON_file.json') as f:
data = json.load(f)
group_chat_id = 'CHAT_ID_HERE'
hbot = telebot.TeleBot('BOT_TOKEN_HERE')
hbot.send_photo(chat_id = group_chat_id, caption = data, photo = open('C:/Users/.../image.jpg', 'rb'))
temp = ""
#hbot.message_handler(func=lambda message: True)
def get_input(message):
global temp
message_str = str(message.text)
message_str = message_str.strip()
temp = message_str
print(temp)
with open('JSON_file.json', 'w') as json_file:
json.dump(temp, json_file)
hbot.stop_polling()
if temp != "":
quit()
return
if __name__ == "__main__":
hbot.polling()
I run the code(s) using an executable .bat file, however, the code below does not quit once a message is received. Does anyone know why the quit() command does not stop my code?
Thanks in advance)

I'd recommend using sys.exit instead of quit: https://docs.python.org/3/library/sys.html#sys.exit
In python, we have an in-built quit() function which is used to exit a python program. When it encounters the quit() function in the system, it terminates the execution of the program completely.
It should not be used in production code and this function should only be used in the interpreter.
Source: https://pythonguides.com/python-exit-command/

Related

How to run a seperate python program within a python program?

I am trying to implement a program that is executing another program over and over until the second program returns a proper output.
But the first program must not be halted after an error that occurred in the second program. I tried something like this, but the exec() function is not what I am looking for.
input_file = 'report.txt'
source_code = 'insert_prices.py'
correct_flag = 26
current_flag = 0
while(1):
with open(input_file, 'r') as file:
current_flag = int(file. readline().split(None, 1)[0])
if(current_flag == correct_flag):
break
else:
exec(open(source_code, encoding='utf-8').read())

Endless loop when importing a variable from another file in Python

I have a file called main.py and based on the user input I want to run the code either from file export.py, either from file import.py. This is how my code from main.py looks:
print("Hi, " + os.getlogin() + "!")
print("Extracting filenames...")
path = input('Tell me the path!\n')
filenames = [x for x in os.listdir(path)]
ID = [f for f in filenames if re.search("(?<=ID)(\d+)", f)]
filestxt = "Files.txt"
idtxt = "ID.txt"
PathFiles = os.path.join(path, filestxt)
PathID = os.path.join(path, idtxt)
file = open(PathFiles, "w+")
file.write('\n'.join(ID))
file.close()
with open(PathID, 'w') as f:
for item in ID:
list = re.findall("(?<=ID)(\d+)", item)
string = ('\n'.join(list))
f.write("%s\n" % string)
key = input("Export or Import(e/i)?:")
if key == 'e':
os.system('python export.py')
When I am hitting the 'e' button Python is running the code from export.py, but when it gets to the line
from main import PathID
instead of importing the variable which I need for the following function
with open(PathID) as f:
for line in f:
...
the code from main.py is running again and again from the beginning and I get the following lines in the console:
"Hi, " + os.getlogin() + "!"
"Extracting filenames..."
'Tell me the path!\n'
"Export or Import(e/i)?:"
All I want in export.py is to tell Python to read the ID.txt file from the path I have specified in the main.py file.
How can I call the function from main.py in export.py without getting this endless loop?
Try to use
if __name__ == '__main__':
before
key = input ("Export or Import (e / i) ?:")
if key == 'e':
os.system ('python export.py')
or before any code that should always be executed at startup.
To expand on Jossnix's answer:
When you execute os.system('python export.py'), you're launching a separate Python interpreter process.
When you execute from main import PathID within export.py, all of the code in main.py is run, and then, once it's finished running, the control flow is returned to export.py and it has access to PathID. The problem is that, as it stands, your main.py asks for user input. So, your main.py is stuck waiting for user input - you have to provide the input again to this new Python interpreter session! Hence, export.py is stuck while trying to import main.
Jossnix's solution works because it ensures that the user input component of main.py does not get run if main.py is being imported from another module, but will be run if main.py is executed as the main script.
I think you should get rid of the os.system('python export.py') line entirely. It's wasteful: you're launching a completely separate Python interpreter session and the print messages in main.py get run again (this is pretty confusing for the end-user!). I'd say you're better off having whatever code you want to run if the user enters the key 'e' wrapped in a function, and then run this function directly from main.py (if the user has indeed entered 'e'). You could do this: Create such a function (f) in export.py, taking a PathID argument. Then, within main.py, from export import f. Finally, if the user entered 'e', run f(PathID, ...).

Python script runs fine from terminal but crashes when run from crontab

I have a simple python script that takes screenshots of a computer that is running Ubuntu. I want it to run automatically on startup, so I put #reboot python3 /bin/program.py in the non-sudo version of crontab.
The program works fine when run from terminal, but gives the error pyscreenshot.err.FailedBackendError. I put it in a try loop, and had it write all exceptions to a file, and that's how I found the error message, "All backends failed."
It has something to do with the program 'pyscreenshot' not working correctly.
import pyscreenshot as screen
import os
from numpy import random
from time import sleep
from os.path import expanduser
TMP_SCREEN_PATH = expanduser('~') + '/.UE/tmp.png'
LOG_FILE_PATH = expanduser('~') + '/.UE/log.txt'
GRAB_DELAY_RANGE = (1, 10)
def screenshot(save_path=TMP_SCREEN_PATH):
img = screen.grab()
img.save(save_path)
def delay(delay_range):
sleep_time = random.randint(delay_range[0], delay_range[1])
print(f"Sleeping for {sleep_time} seconds")
sleep(sleep_time)
def main():
try:
while True:
screenshot()
delay(GRAB_DELAY_RANGE)
except KeyboardInterrupt:
print("Nope")
main()
except Exception as e:
print(e)
with open(LOG_FILE_PATH, 'a') as f:
f.write(str(type(e))+str(e)+'\n')
sleep(5)
main()
f = open(LOG_FILE_PATH, 'w+')
f.write('Startup')
f.close()
main()
I need one of the following solutions:
Simply fix the problem
Another way to run a program at startup
A different module to take screenshots with
Any help is appreciated, thanks
If the user that the cron job runs as is also logged in on the console (you mention a reboot, so I'm guessing that you have enabled autologin), then your cron job might work if you also add:
os.environ["DISPLAY"] = ":0"
This worked for me on Ubuntu in a test using cron and a simplified version of your script:
import os
import pyscreenshot as screen
os.environ["DISPLAY"] = ":0"
img = screen.grab()
img.save("/tmp/test.png")
If it doesn't work for you, then you might also have to try setting the value of the XAUTHORITY environment variable to the value found in the environment of the user's interactive processes, which could be extracted using the psutil package, but let's hope this isn't needed.

Python Run Code When Thread Finishes

I am currently writing a simple file server using Python and the Socket library. I have most of it finished, and now I'm writing a way to push an update to the server. Here's what I expect it to do:
Client Should Send New Python File To Server
Server Deletes File Previous Python File
Server Downloads Python File
Server Runs New Code
Server With Old Code Quits
As of right now, my program can do 1-3, but it still cannot run the new code and quit the program. Since the server program is about 100 lines long, here's a link to the pastebin with the code. If you want to use the uploader too, here it is.
Looking at my code, the problem either lies in my update code:
class updServer(Thread):
def __init__(self,s):
Thread.__init__(self)
self.s = s
def run(self):
os.remove(os.path.realpath(__file__))
fn = self.s.recv(2048)
with open(fn, 'wb') as f:
still_data = True
while still_data:
data = self.s.recv(2048)
if not data:
still_data = False
if data == '':
still_data = False
f.write(data)
f.flush()
os.fsync(f.fileno())
f.close()
global name_of_file
name_of_file = fn
return None
Or in the way that I'm trying to run the new program under it:
elif file_name_sent == b'to update server':
new_t = updServer(conn)
threads.append(new_t)
new_t.start()
global name_of_file
execfile(name_of_file)
os._exit(0)
Note: I have also tried to use os.command and subprocess.call, and I also know that python is on my PATH. Instructions for the uploader are here if you want them.

How to terminate external program or window using python

I am trying to close the program, in this case spotify, but I am keep getting semantic mistake. Here is my code:
sup_programs.txt
{
'spotify': ['C:/Users/Daniiar/AppData/Roaming/Spotify/Spotify.exe']
}
script:
class Path(object):
import ast
sup_programs_txt = open('sup_programs.txt', 'r')
s_p = sup_programs_txt.read()
paths = ast.literal_eval(s_p)
sup_programs_txt.close()
paths = Path().paths
program_name = 'spotify'
def open_program(path_name):
import subprocess
subprocess.Popen(path_name)
open_program(paths[program_name])
def close_program(path_name):
import subprocess
p = subprocess.Popen(path_name)
p.terminate()
yes = input(" ... ")
if 'close' in yes or 'yes' in yes:
close_program(paths[program_name])
else:
print('too bad')
I used kill() and terminate() neither of them have worked and os.system('TASKKILL ')
Is there any other methods or am using existing ones incorrectly?
BTW, I am using windows 10 and python 3.5 . Thank you for your help
your open_program function is recursive ???
Anyway, to open your program, you can do it by the path name. It then returns a handle on a subprocess.
To close it, just call the terminate method on that handle
example below opens notepad, waits 3 seconds, then closes it.
import time
import subprocess
def open_program(path_name):
return subprocess.Popen(path_name)
def close_program(p):
p.terminate()
p=open_program("notepad")
time.sleep(3)
close_program(p)

Categories

Resources