I use json to store currency and I made a few games where people can earn currency by playing.
The problem is if 2 or more user use the command at the same time only one user will win/lose the currency in json. Is there a way to fix this?
This is an example code of the game that I made
I changed my database to sqlite
You need to use await when you read from or write to file, else the bot will wait for the operation to finish.
The await wrapper makes your bot jump to another line of code and not wait for I/O processes.
I'm making a bot with python-telegram-bot that sends you several messages in a row in response to a single command. When all messages arrive at once, it is inconvenient to the user. I want to add a pause between sending and send action=ChatAction.TYPING between them. Is there any convenient way to do this without using something like time.sleep()?
I believe that the framework's JobQueue solves your problem. It allows you to schedule messages to be sent at some point in the future.
Quote:
You can also add a job that will be executed only once, with a delay:
>>> def callback_30(bot, job):
... bot.send_message(chat_id='#examplechannel',
... text='A single message with 30s delay')
...
>>> j.run_once(callback_30, 30)
In thirty seconds you should receive the message from callback_30.
I want to write a simple reminder-bot for telegram. Bot gets from user time (Hours:Minutes) and saves it. When system time equals to users remind time, bot sends message to user.
This is how i track current time:
import time
def timer():
now = time.strftime('%X').split(':')[0:2]
return now
The question is:
How can I make my code wait till time to send message comes without using time.sleep() and checking current time each minute (uses too much memory of raspberrypi)?
If you use python-telegram-bot library, you can use the JobQueue to set up timed jobs.
See here for an example.
I have my own jabber bot, and today I made a new plugin, which is to send message for all users. My code was working well, but I have a small problem; when I give my bot the command to send a message, my bot gets stuck and disconnects.
I know why my bot gets stuck and disconnects; I have more than 2000 users, so my bot cannot send a message at the same time for all users. Is there any method in Python to make my code send the message for each user after N seconds? I mean have the bot send MSG for user1, then wait for N seconds and send for user2, etc.
I hope my idea is clear. This is my code:
def send_msg(type, source, parameters):
ADMINFILE = 'modules/xmpp/users.cfg'
fp = open(ADMINFILE, 'r')
users = eval(fp.read())
if parameters:
for z in users:
msg(z, u"MSG from Admin:\n" +parameters)
reply(type, source, u"MSG has been sent!")
else:
reply(type, source, u"Error! please try again.")
register_command_handler(send_msg, 'msg', ['all','amsg'], 0,'Sends a message to all users')
I believe you are looking for time.sleep(secs). From the docs:
Suspend execution for the given number of seconds. The argument may be
a floating point number to indicate a more precise sleep time. The
actual suspension time may be less than that requested because any
caught signal will terminate the sleep() following execution of that
signal’s catching routine. Also, the suspension time may be longer
than requested by an arbitrary amount because of the scheduling of
other activity in the system.
After each send you can delay for time.sleep(seconds) before sending your next message.
I wrote a python script to monitor a log file on a CentOS server for a specific value and send an email when it finds it. It runs as a cron every 5 minutes.
My question is what is the best way to put this script to sleep after it has sent the first email. I don't want it to be sending emails every 5 mins, but it needs to wake up and check the log again after an hour or so. This is assuming the problem can be fixed in under an hour. The people who are receiving the email don't have shell access to disable the cron.
I thought about sleep but I'm not sure if cron will try to run the script again if another process is active (sleeping).
cron will absolutely run the script again. You need to think this through a little more carefully than just "sleep" and "email every 10 minutes."
You need to write out your use cases.
System sends message and user does something.
System sends message and user does nothing. Why email the user again? What does 2 emails do that 1 email didn't do? Perhaps you should SMS or email someone else.
How does the user register that something was done? How will they cancel or stop this cycle of messages?
What if something is found in the log, an email is sent and then (before the sleep finishes) the thing is found again in the log. Is that a second email? It is two incidents. Or is that one email with two incidents?
#Lennart, #S. Lott: I think the question was somewhat the other way around - the script runs as a cron job every five minutes, but after sending an error-email it shouldn't send another for at least an hour (even if the error state persists).
The obvious answer, I think, is to save a self-log - for each problem detected, an id and a timestamp for the last time an email was sent. When a problem is detected, check the self-log; if the last email for this problem-id was less than an hour ago, don't send the email. Then your program can exit normally until called again by cron.
When your scripts sends email, make it also create a txt file "email_sent.txt". Then make it check for existence of this txt file before sending email. If it exists, don't send email. If it does not exist, send email and create the text file.
The text files serves as an indicator that email has already been sent and it does not need to be sent again.
You are running it every five minutes. Why would you sleep it? Just exit. If you want to make sure it doesn't send email every five minutes, then make the program only send an email if there is anything to send.
If you sleep it for an hour, and run it every five minutes, after an hour you'll have 12 copies running (and twelve emails sent) so that's clearly not the way to go forward. :-)
Another way to go about this might be to run your script as a daemon and, instead of having cron run it every five minutes, put your logic in a loop. Something like this...
while True:
# The check_my_logfile() looks for what you want.
# If it finds what you're looking for, it sends
# an email and returns True.
if check_my_logfile():
# Then you can sleep for 10 minutes.
time.sleep(600)
# Otherwise, you can sleep for 5 minutes.
else:
time.sleep(300)
Since you are monitoring a log file, It might be worth checking into things that already do log file monitoring. Logwatch is one, but there are log analyzing tools, that handle all of these things for you:
http://chuvakin.blogspot.com/2010/09/on-free-log-management-tools.html
Is a good wrap-up of some options. They would handle yelling at people. Also there are system monitoring tools such as opennms or nagios, etc. They also do these things.
I agree with what other people have said above, basically cron ALWAYS runs the job at the specified time, there is a tool called at which lets you run jobs in the future, so you could batch a job for 5 minutes, and then at runtime decide, when do I need to run again, and submit a job to at for whatever time you need it to run again (be it 5 minutes, 10 minutes or an hour). You'd still need to keep state somewhere (like what #infrared said) that would figure out what got sent when, and if you should care some more.
I'd still suggest using a system monitoring tool, which would easily grow and scale and handles people being able to say 'I'm working on XX NOW stop yelling at me' for instance.
Good luck!