Handle messages one at time on python telebot - queue

i'm using a script (.bat) who do some download based on a link received on telegram, but at my code it can run multiple times, but i need to handle one message at time, and every message took like 15minutes to complete.
my atual code:
def handle_text_doc(message):
print ("bot new link to download")
with open ("test.txt","r") as arquivo:
email = arquivo.read()
#print (email)
with open ("test.txt","w") as arquivo:
texto = str(message)
arquivo.write(texto)
with open ("test.txt","r") as arquivo:
email = arquivo.read()
subprocess.call([r'c:\downloads\fullrun.bat'])
print ("terminado")
i need that subprocess finished before it starts again, but sometimes i receive like 10 messages, and i need to solve the .bat file for every messsage i receive, one at a time.
sorry for bad english

So you should use async version of telebot - click here to know more
Then your code should be something like this
async def handle_text_doc(message):
print ("bot new link to download")
await with open ("test.txt","r") as arquivo:
await email = arquivo.read()
#print (email)
await with open ("test.txt","w") as arquivo:
texto = str(message)
await arquivo.write(texto)
await with open ("test.txt","r") as arquivo:
email = arquivo.read()
await subprocess.call([r'c:\downloads\fullrun.bat'])
print ("terminado")

Related

How create a Login with Kivy and Python

I would like to create a GUI with Kivy to login to a website, Is it possible?
Here is a part of the code.
Instead of logging in from the terminal I would like to create an android application that does some web scraping for me once I log in..
def login():
driver.get("https://sgv.ivu-cloud.com/mbweb/j_security_check")
# find username/email field and send the username itself to the input field
driver.find_element(By.ID, 'j_username').send_keys(username)
# find password input field and insert password as well
driver.find_element(By.ID, 'j_password').send_keys(password)
# click login button
driver.find_element(By.ID, 'login-button').click()
# wait the ready state to be complete
WebDriverWait(driver=driver, timeout=5).until(
lambda x: x.execute_script("return document.readyState === 'complete'")
)
error_message = "Login fehlgeschlagen."
# get the errors (if there are)
errors = driver.find_elements(By.CLASS_NAME, "highlight_login")# print the errors optionally
#for e in errors:
# print(e)
# if we find that error message within errors, then login is failed
if any(errors):
print("Anmeldung fehlgeschlagen!")
print('Falscher Benutzername oder Passwort!\nPrüfe die Exceldatei "LoginDaten.xlsx", ob die Felder korrekt ausgefüllt sind!')
exit()
else:
print("Anmeldung erfolgreich!")
loggedin=True
login()

Python3 Win32com Copy body of an email and paste to a new excel file

I'm trying to copy paste an html table received by outlook email to a new excel spreadsheet but I get a "pywintypes.com_error." Seeking a more pythonic way to do a the equivalent of a "Control+A" on an email body and paste to a new spreadsheet.
The relevant pieces of code are:
import win32com.client
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
# Select main Inbox
inbox = outlook.GetDefaultFolder(6)
messages = inbox.Items
try:
for message in messages:
try:
if message.subject == 'myemailed Report':
print('Sender:' , message.sender)
print(message.subject)
mailItem = message.HTMLBody # <----Attempting to copy the body of the selected email.
# Start an instance of Excel
Xlsx = win32com.client.Dispatch("Excel.Application")
# Prevent Excel from asking questions.
Xlsx.DisplayAlerts = True # will change to False
Xlsx.Visible = True # will change to False
# Create a new Excel Workbook
workbook = Xlsx.Workbooks.Add()
ws = workbook.Sheets("Sheet1")
ws.Range('a7').select
ws.Paste(mailItem) # <--------------- Generates Error
workbook.SaveAs(mydesktop+'UpdatedSheet.xlsx')
# Quit Excel
Xlsx.Quit()
except:
x=1
except:
x=1
I get a message: Traceback (most recent call last):
File "", line 1, in
ws.Paste(mailItem)
File ">", line 3, in Paste
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'Microsoft Excel', 'Paste method of Worksheet class failed', 'xlmain11.chm', 0, -2146827284), None)
Is there a better way? Help is appreciated!
ws.Paste(mailItem) is the main part of the problem. Code should be:
ws.Paste()
However - copying the email body as if hitting "Ctrl-A" is a little more involved and there are a lot of almost answers. I managed to get the following work but I don't know why it works.
I used import pyperclip which requires pip install pyperclip, along with the following code:
import pyperclip
def copy(text):
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text, win32clipboard.CF_UNICODETEXT)
win32clipboard.CloseClipboard()
def paste():
win32clipboard.OpenClipboard()
data = win32clipboard.GetClipboardData(win32clipboard.CF_UNICODETEXT)
win32clipboard.CloseClipboard()
return data
Then later on...
mailItem = message.HTMLBody
pyperclip.copy(mailItem)
# Start an instance of Excel
Xlsx = win32com.client.Dispatch("Excel.Application")
# Create a new Excel Workbook
workbook = Xlsx.Workbooks.Add()
ws = workbook.Sheets("Sheet1")
ws.Range('a1').select
ws.Paste()
ws.Range('a1').select
workbook.SaveAs(myexcel.xlsx')
I tried doing this without using pyperclip but the combination of the two def's in the beginning and the ws.Paste() worked.

An error in my code to be a simple ftp

I met an error when running codes at the bottom. It's like a simple ftp.
I use python2.6.6 and CentOS release 6.8
In most linux server, it gets right results like this:(I'm very sorry that I have just sign up and couldn't )
Clinet:
[root#Test ftp]# python client.py
path:put|/home/aaa.txt
Server:
[root#Test ftp]# python server.py
connected...
pre_data:put|aaa.txt|4
cmd: put
file_name: aaa.txt
file_size: 4
upload successed.
But I get errors in some server(such as my own VM in my PC). I have done lots of tests(python2.6/python2.7, Centos6.5/Centos6.7) and found this error is not because them. Here is the error imformation:
[root#Lewis-VM ftp]# python server.py
connected...
pre_data:put|aaa.txt|7sdfsdf ###Here gets the wrong result, "sdfsdf" is the content of /home/aaa.txt and it shouldn't be sent here to 'file_size' and so it cause the "ValueError" below
cmd: put
file_name: aaa.txt
file_size: 7sdfsdf
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 10699)
Traceback (most recent call last):
File "/usr/lib64/python2.6/SocketServer.py", line 570, in process_request_thread
self.finish_request(request, client_address)
File "/usr/lib64/python2.6/SocketServer.py", line 332, in finish_request
self.RequestHandlerClass(request, client_address, self)
File "/usr/lib64/python2.6/SocketServer.py", line 627, in __init__
self.handle()
File "server.py", line 30, in handle
if int(file_size)>recv_size:
ValueError: invalid literal for int() with base 10: '7sdfsdf\n'
What's more, I found that if I insert a time.sleep(1) between sk.send(cmd+"|"+file_name+'|'+str(file_size)) and sk.send(data) in client.py, the error will disappear. I have said that I did tests in different system and python versions and the error is not because them. So I guess that is it because of some system configs? I have check about socket.send() and socket.recv() in python.org but fount nothing helpful. So could somebody help me to explain why this happend?
The code are here:
#!/usr/bin/env python
#coding:utf-8
################
#This is server#
################
import SocketServer
import os
class MyServer(SocketServer.BaseRequestHandler):
def handle(self):
base_path = '/home/ftp/file'
conn = self.request
print 'connected...'
while True:
#####receive pre_data: we should get data like 'put|/home/aaa|7'
pre_data = conn.recv(1024)
print 'pre_data:' + pre_data
cmd,file_name,file_size = pre_data.split('|')
print 'cmd: ' + cmd
print 'file_name: '+ file_name
print 'file_size: '+ file_size
recv_size = 0
file_dir = os.path.join(base_path,file_name)
f = file(file_dir,'wb')
Flag = True
####receive 1024bytes each time
while Flag:
if int(file_size)>recv_size:
data = conn.recv(1024)
recv_size+=len(data)
else:
recv_size = 0
Flag = False
continue
f.write(data)
print 'upload successed.'
f.close()
instance = SocketServer.ThreadingTCPServer(('127.0.0.1',9999),MyServer)
instance.serve_forever()
#!/usr/bin/env python
#coding:utf-8
################
#This is client#
################
import socket
import sys
import os
ip_port = ('127.0.0.1',9999)
sk = socket.socket()
sk.connect(ip_port)
while True:
input = raw_input('path:')
#####we should input like 'put|/home/aaa.txt'
cmd,path = input.split('|')
file_name = os.path.basename(path)
file_size=os.stat(path).st_size
sk.send(cmd+"|"+file_name+'|'+str(file_size))
send_size = 0
f= file(path,'rb')
Flag = True
#####read 1024 bytes and send it to server each time
while Flag:
if send_size + 1024 >file_size:
data = f.read(file_size-send_size)
Flag = False
else:
data = f.read(1024)
send_size+=1024
sk.send(data)
f.close()
sk.close()
The TCP is a stream of data. That is the problem. TCP do not need to keep message boundaries. So when a client calls something like
connection.send("0123456789")
connection.send("ABCDEFGHIJ")
then a naive server like
while True;
data = conn.recv(1024)
print data + "_"
may print any of:
0123456789_ABCDEFGHIJ_
0123456789ABCDEFGHIJ_
0_1_2_3_4_5_6_7_8_9_A_B_C_D_E_F_G_H_I_J_
The server has no chance to recognize how many sends client called because the TCP stack at client side just inserted data to a stream and the server must be able to process the data received in different number of buffers than the client used.
Your server must contain a logic to separate the header and the data. All of application protocols based on TCP use a mechanism to identify application level boundaries. For example HTTP separates headers and body by an empty line and it informs about the body length in a separate header.
Your program works correctly when server receives a header with the command, name and size in a separate buffer it it fails when client is fast enough and push the data into stream quickly and the server reads header and data in one chunk.

how can i send facebook message using selenium webdriver

I am able to login on facebook, able to open chat but unable to send any message
Below program code I have used:
//Login on FB >> Working fine
driver.findElement(By.xpath(".//*[#id='email']")).sendKeys("******#gmail.com");
driver.findElement(By.xpath(".//*[#id='pass']")).sendKeys("********");
driver.findElement(By.xpath(".//*[#id='u_0_l']")).click();
// click on message icon >> Working fine
driver.findElement(By.xpath(".//*[#id='u_0_h']/li[1]/div/a/span")).click();
//click on friends name, to whom i want to send message >> Working fine
driver.findElement(By.xpath("/html/body/div[1]/div[1]/div/div/div/div[1]/div/div/div[2]/ul/li[5]/div/div[2]/div/div[3]/div/div[1]/div/div/ul/li[2]/a")).click();
Thread.sleep(5000);
//Send message >>>> here, i am not getting any response, code run without entered any message or error
driver.findElement(By.xpath(".//*[#class='_552h _35li _n4k']")).sendKeys("Hiii");
driver.findElement(By.xpath("/html/body/div/div[5]/div[1]/div/div/div[1]/div/div[1]/div[2]/div/div/div/div/div[4]/div[5]/div[1]/div/div/div[2]/div/div/div")).sendKeys(Keys.ENTER);;
I have used this code, it works for me.
driver.findElement(By.xpath("//div[contains(#class,'_5rpu') and #role='combobox']")).sendKeys("hi"+Keys.ENTER);
require 'selenium-webdriver'
#driver = Selenium::WebDriver.for :chrome
#driver.get 'https://www.facebook.com/fname.lname?fref=none'
a = #driver.find_element(:xpath, '//[#id="email"]').send_keys('aaa#gmail.com')
a = #driver.find_element(:xpath, '//*[#id="pass"]').send_keys('12345678')
a = #driver.find_element(:xpath, '//*[#value="Log In"]').click
sleep 5
a = #driver.find_element(:xpath, '//a[#href="/messages/fname.lname" and #role="button"]').click
sleep 2;p 'This is Where I clicked/initiated the Send Message '
a = #driver.find_element(:xpath, '//div[#class="_1ia"]/descendant::div[#class="_5rpu" and #role="textbox"]')
a.send_keys('Hi There') # This is where I entered the keys and Did Enter
a.send_keys:enter
The correct answer since the #role has changed is :
WebElement sendmsg = driver
.findElement(By.xpath("//div[#class='_1ia']/descendant::div[#class='_5rpu' and #role='combobox']"));
sendmsg.sendKeys("Just testing: using selenium webdriver" + Keys.ENTER);

Python 3.4 email to multiple receivers throws an ERROR

I'm writing a script to send an email to more than one email account, but not able, yet.
It works as it is below, but if I set receivers='xxx#xxx.com','yyy#yyy.com' it won't work, it throws an error:
AttributeError: 'tuple' object has no attribute 'encode'.
How can I set receivers=?
def send_email (out_file):
sender = 'xxx#xxx.com'
receivers = 'xxx#xxx.com'
email_pass = 'aaaa'
filematch=re.findall('NE.*\.txt',out_file.name)
subject = ("NEXXXX_price_update")
message = ("The following file was forwarded to your ftp account %s " %filematch)
msg = 'Subject: %s\n%s' %(subject, message)
try:
smtpObj = smtplib.SMTP_SSL('smtp.gmail.com',0)
smtpObj.login(receivers, email_pass)
smtpObj.sendmail(sender, receivers, msg)
print ("Successfully sent email")
except SMTPException:
print ("email NOT successful")
print(SMTPException.__cause__)
smtpObj.quit()
You assign wrongly
receivers='xxx#xxx.com','yyy#yyy.com'
You suppose to assign as a tuple or list, not sure 100% which.
Give a try:
receivers=('xxx#xxx.com','yyy#yyy.com')
or
receivers=['xxx#xxx.com','yyy#yyy.com']