how to run an external function with variables from State? - selenium

this function must be run in the file where the bot is located
def start_pars():
from mainaio import data
username_input = driver.find_element(By.XPATH,
'/html/body/div/div/main/div/div/div/div[1]/form/div[1]/div[1]/div/input')
username_input.clear()
username_input.send_keys(data["username"])
pass_input = driver.find_element(By.XPATH,
'/html/body/div/div/main/div/div/div/div[1]/form/div[1]/div[2]/div/input')
pass_input.clear()
pass_input.send_keys(data["password"])
driver.find_element(By.XPATH, '/html/body/div/div/main/div/div/div/div[1]/form/div[2]/button').click()
time.sleep(1)
username1 = driver.find_element(By.XPATH, '/html/body/div[1]/nav[2]/div[2]/div/div[2]/div[2]/div')
print(username1.text)
less1 = []
lessundscore = driver.find_elements(By.XPATH, '/html/body/div[1]/div/main/div/div[2]/div/div[3]/div[1]')
for value in zip(lessundscore):
less1 += value
for val in less1:
print(val.text)
return username1, less1
items from the state must be transferred to the sending keys
class Registration(StatesGroup):
username = State()
password = State()
username = message.text
await state.update_data(username=username)
assword = message.text
await state.update_data(password=password)
data = await state.get_data()
I tried to run in the last registration function start_pars(data['username'], data['password'])

Related

the post sent by the bot telegram is not deleted for all users

I have a function which allows to send a message to all users who clicked the start button.
#dp.message_handler(commands=['Yes'], state=Post.send_post)
async def process_name(message: Message, state: FSMContext):
for admin in admins:
if message.from_user.id == admin:
async with state.proxy() as data:
data['send_post'] = message.text
conn = sqlite3.connect('data.db')
cur = conn.cursor()
cur.execute(f'SELECT * FROM users')
result = cur.fetchall()
await state.finish()
print(result)
try:
for z in range(len(result)):
print(result[z][0])
await dp.bot.send_photo(chat_id=result[z][0], photo=data['photo'], caption=data['CAPTHION'], reply_markup=kb)
print(z)
test = message.message_id + 1
await dp.bot.send_message(chat_id=result[z][0], text=f'id поста {test}')
except BotBlocked:
print('Пользователь заблокировал бота')
except ChatNotFound:
print('Пользователь не запускал бота')
Also, there is a function that allows you to delete messages by id. The administrator enters the deleted command, after which the bot asks to enter its id. When the Administrator enters an id, the bot deletes messages through a loop, iterating over the id. But for some reason, it only deletes a post from one user, then it throws an error
aiogram.utils.exceptions.MessageToDeleteNotFound: Message to delete not found
Please help me I can't figure out why
#dp.message_handler(commands=['deleted'], state=None)
async def send_id(message: Message):
for admin in admins:
if message.from_user.id == admin:
await Post.Sen_id.set()
await dp.bot.send_message(chat_id=admin, text='Введите ID поста, который нужно удалить.')
await Post.next()
#dp.message_handler(state=Post.del_mess)
async def deleted_post(message: Message, state: FSMContext):
for admin in admins:
if message.from_user.id == admin:
async with state.proxy() as data:
data['sen_id'] = message.text
try:
conn = sqlite3.connect('data.db')
cur = conn.cursor()
cur.execute(f'SELECT * FROM users')
result = cur.fetchall()
#message_ids = int(data['sen_id'])
for z in range(len(result)):
print('/////////////deleted/////////////')
print(result)
print(z)
await dp.bot.delete_message(chat_id=result[z][0], message_id=data['sen_id'])
print('Сообщение удалено')
#chat_id = message.chat.id
#await dp.bot.delete_message(message.chat.id, message_ids)
await dp.bot.send_message(chat_id=admin, text='пост удален')
except BotBlocked:
print('Пользователь заблокировал бота')
except ChatNotFound:
print('Пользователь не запускал бота')
This is a code that does what you wish for - deleting message with given message_id in every chat where that message exist. Later I'll explain why this is actually not a good solution.
The problem is with the placing of the try-except block. In your code, if deleting the message fails for a single user, for all users that are past him in the database the deletion will not be even attempted. Solution would be to place the try-except block in the for loop.
...
if message.from_user.id == admin:
async with state.proxy() as data:
data['sen_id'] = message.text
conn = sqlite3.connect('data.db')
cur = conn.cursor()
cur.execute(f'SELECT * FROM users')
result = cur.fetchall()
#message_ids = int(data['sen_id'])
for z in range(len(result)):
try:
print('/////////////deleted/////////////')
print(result)
print(z)
await dp.bot.delete_message(chat_id=result[z][0], message_id=data['sen_id'])
print('Сообщение удалено')
#chat_id = message.chat.id
#await dp.bot.delete_message(message.chat.id, message_ids)
await dp.bot.send_message(chat_id=admin, text='пост удален')
except BotBlocked:
print('Пользователь заблокировал бота')
except ChatNotFound:
print('Пользователь не запускал бота')
except Exception as e:
print(e)
...
However, after testing this approach, I believe you will realise that there is a problem: if you send a "post" to multiple users, it may have a different message_id for different users! So you would have to use a different approach.

How can I access what the user passes in the command to use it the command error handler? discord.py

How can I access what the user passes in the command user so I can use it the user.error handler?
here's what I've tried and didn't work:
#commands.command(aliases= ["info"])
async def user(self, ctx, *, member: discord.Member=None):
colors = [0xad1457, 0xe67e22, 0x992d22, 0x607d8b, 0x7289da, 0x71368a, 0x11806a]
if member == None:
embed = discord.Embed(color = random.choice(colors))
embed.add_field(name = "**Joined Discord**:", value = "`" + ctx.author.created_at.strftime("%d/%m/%Y %I:%M") + "`")
embed.add_field(name = "**Joined Server:**", value = "`" + ctx.author.joined_at.strftime("%d/%m/%Y %I:%M") + "`")
embed.set_footer(text = f"{ctx.author.name}")
embed.set_image(url = f"{ctx.author.avatar_url}")
await ctx.send(embed = embed)
else:
embed = discord.Embed(color = random.choice(colors))
embed.add_field(name = "**Joined Discord**:", value = "`" + member.created_at.strftime("%d/%m/%Y %I:%M") + "`")
embed.add_field(name = "**Joined Server:**", value = "`" + member.joined_at.strftime("%d/%m/%Y %I:%M") + "`")
embed.set_footer(text = f"{member.name}")
embed.set_image(url = f"{member.avatar_url}")
await ctx.send(embed = embed)
#user.error
async def user_error(self, ctx, error):
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send(f"**Wrong format. Use {ctx.prefix}user <user>**")
elif isinstance(error, commands.MemberNotFound):
await ctx.send(f"**🙄 - {ctx.author.name}**, I can't find {member.id} in the server.")
else:
raise error
so I want to access what the user passes in the command so I can use it in the command handler.
and another question, how can I make the aliases doesn't need the prefix to run the command
example: in my code above I have info as aliases, I want if the user typed info(without the prefix) the bot will answer.
You can get the passed arguments and keyword arguments with ctx.args and ctx.kwargs.
EDIT:
#user.error
async def user_error(self, ctx, error):
if isinstance(error, commands.MissingRequiredArgument):
await ctx.send(f"**Wrong format. Use {ctx.prefix}user <user>**")
elif isinstance(error, commands.MemberNotFound):
await ctx.send(f"**🙄 - {ctx.author.name}**, I can't find a member with {error.argument} in the server.")
else:
raise error

How to assert an element is present after a click in Hound?

I'm using Hound as webdriver framework for leveraging Selenium in Elixir. I'm testing facebook account creation. After I fill out a negative test (firstname = Roberto, lastname = asdlkfj;)I click submit and I am trying to get an error for not having a correct last name. The problem is Hound isn't waiting for the element to be displayed and returns an element not found error. How can I handle this and have the test wait until the element is loaded? Here's my code:
test "Last name with random characters" do
counter = :rand.uniform(100)
navigate_to "https://www.facebook.com"
first_name = find_element(:name, "firstname")
fill_field(first_name, "Jorge")
last_name = find_element(:name, "lastname")
fill_field(last_name, "asdfja;lsdf")
email_input = "robbie#{counter}#gmail.com"
email = find_element(:name, "reg_email__")
fill_field(email, email_input)
confirm_email = find_element(:name, "reg_email_confirmation__")
fill_field(confirm_email, email_input)
password_input = "123456Test"
password = find_element(:name, "reg_passwd__")
fill_field(password, password_input)
#Birthday
birth_month = find_element(:css, "#month > option:nth-child(5)")
birth_day = find_element(:css, "#day > option:nth-child(25)")
birth_year = find_element(:css, "#year > option:nth-child(22)")
click(birth_month)
click(birth_day)
click(birth_year)
#gender
select_gender = find_element(:css, "#u_0_s > span:nth-child(2)")
click(select_gender)
sign_up_button = find_element(:name, "websubmit")
click(sign_up_button)
search = find_element(:id, "#reg_error_inner")
# found = element_displayed?("#reg_error_inner")
IO.puts(search)
# assert found == true
# :timer.sleep(10000)
end```
Use search_element instead of find_element. search_element will return {:ok, element} on success and {:error, error} on failure. If you just want to assert the element exists, then you can:
assert {:ok, _} = search_element(:id, "#reg_error_inner")
If you want to also have it in a variable for further processing, then:
assert {:ok, element} = search_element(:id, "#reg_error_inner")
If you want to convert it to a boolean, then:
match?({:ok, _}, search_element(:id, "#reg_error_inner"))

What scope is needed to use the findReplace function in GoogleSheets API v4?

I want to use the findReplace request in the Google Sheets APIv4. I set up my Scope and request as defined in the Google quickstart guide for the Sheets API in Python and have confirmed that the API can talk to my spreadsheet.
https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets/request#FindReplaceRequest
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
SHEET_ID = myspreadsheetid
creds = None
store = file.Storage('sheets_token.json')
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = client.flow_from_clientsecrets('client_2_https.json', SCOPES)
creds = tools.run_flow(flow, store, http=Http(disable_ssl_certificate_validation=True))
with open('sheets_token.pickle', 'wb') as token:
pickle.dump(creds, token)
adminService = build('sheets', 'v4', http=creds.authorize(Http(disable_ssl_certificate_validation=True)))
def findreplace_request(find, replacement):
findreplace_request = {}
findreplace_request['find'] = find
findreplace_request['replacement'] = replacement
findreplace_request['matchCase'] = True
findreplace_request['matchEntireCell'] = True
findreplace_request['searchByRegex'] = False
findreplace_request['includeFormulas'] = False
findreplace_request['sheetId'] = mysheetid
allSheets = False
request = {}
request['findReplace'] = findreplace_request
return request
body = {}
body.setdefault('requests',[]).append(findreplace_request('#mydate#','TODAY'))
response = adminService.spreadsheets().batchUpdate(spreadsheetId=SHEET_ID, body=my_request).execute()
I clearly set a scope to read and write to/from Google Sheets, but I do not understand why I get an error that says the scope is not set.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\wnh659\AppData\Local\Continuum\anaconda3\lib\site-packages\googleapiclient\_helpers.py", line 130, in positional_wrapper
return wrapped(*args, **kwargs)
File "C:\Users\wnh659\AppData\Local\Continuum\anaconda3\lib\site-packages\googleapiclient\http.py", line 851, in execute
raise HttpError(resp, content, uri=self.uri)
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://sheets.googleapis.com/v4/spreadsheets/1Sx0CJJo-b6Z6JUaQEQ6cJ3Yxtjv3z9BtHN9EHl0-0jU:batchUpdate?alt=json return
ed "Invalid requests[0].findReplace: scope not set.">
You want to use the findReplace request of Sheets API using python.
You have already been able to modify Spreadsheet using Sheets API.
If my understanding is correct, how about this modification? I think that the reason of the error of Invalid requests[0].findReplace: scope not set. is that the scope for replacing the value is not defined. In your request body, the properties of range, sheetId and allSheets are not used. So how about the following modification?
Modified script:
From:
def findreplace_request(find, replacement):
findreplace_request = {}
findreplace_request['find'] = find
findreplace_request['replacement'] = replacement
findreplace_request['matchCase'] = True
findreplace_request['matchEntireCell'] = True
findreplace_request['searchByRegex'] = False
findreplace_request['includeFormulas'] = False
sheetId = mysheetid
allSheets = False
request = {}
request['findReplace'] = findreplace_request
return request
To:
def findreplace_request(find, replacement):
findreplace_request = {}
findreplace_request['find'] = find
findreplace_request['replacement'] = replacement
findreplace_request['matchCase'] = True
findreplace_request['matchEntireCell'] = True
findreplace_request['searchByRegex'] = False
findreplace_request['includeFormulas'] = False
findreplace_request['sheetId'] = mysheetid # Added
allSheets = False
request = {}
request['findReplace'] = findreplace_request
return request
In this modification, find is searched from the sheet of mysheetid. If you want to search the value from all sheets, please use the property of allSheets instead of sheetId.
Note:
If the value of property is boolean, when the property is not used, the value is used as False of the default value.
In your script, I think that the following modification can be also worked.
body = {}
body.setdefault('requests',[]).append(findreplace_request('#mydate#','TODAY'))
response = adminService.spreadsheets().batchUpdate(spreadsheetId=SHEET_ID, body=body).execute()
Reference:
FindReplaceRequest
If I misunderstood your question and this was not the result you want, I apologize.

How to print from odoo/openERP via XML-RPC

Has anybody used openERP/ odoo for printing invoices via XML-RPC. I've been trying to create an xml rpc method for printing with no success.
function printInvoice($values,$model){
$print = new xmlrpc_client($this->server."report");
$print->return_type = 'phpvals';
foreach($values as $k=>$v){
$nval[$k] = new xmlrpcval( $v, xmlrpc_get_type($v) );
}
$msg = new xmlrpcmsg('report');
$msg->addParam(new xmlrpcval($this->database, "string"));
$msg->addParam(new xmlrpcval($this->uid, "int"));
$msg->addParam(new xmlrpcval($this->password, "string"));
$msg->addParam(new xmlrpcval($model, "string"));
$msg->addParam(new xmlrpcval("report", "string"));
$msg->addParam(new xmlrpcval(87, "int"));
$msg->addParam(new xmlrpcval($nval,"struct"));
$resp = $print->send($msg);
if ($resp->faultCode())
return $resp->faultString();
else
return $resp->value();
}
this is the code that I have so far, first of all i want to generate a report and then print it.
I figured it out a simple way to do it, you just pass the id of invoice or order in the links and this dynamically creates a pdf for the report, or instead of the pdf you can use 'html' which generates an html ready for print for the invoice like this:
http://serverurl:port/report/html/account.report_invoice/(id of invoice);
Here is the code if it helps someone.
function printInvoice($id,$type){
if($type == 'invoice')
{
return "http://serverurl:port/report/pdf/account.report_invoice/".$id;
}
else if($type == 'order')
{
return "http://serverurl:port/report/pdf/sale.report_saleorder/".$id;
}
else
{
return false;
}
}
There is another way that works even when session_id is missing. You should add a function on the server side which will return a pdf:
from openerp import models, api
from openerp.http import request
class AccountInvoice(models.Model):
_inherit = 'account.invoice'
#api.multi
def json_pdf(self):
request.website_multilang = False
pdf = self.env['report'].get_pdf(self, 'account.report_invoice')
if pdf:
return {'data': pdf.encode('base64'), 'name': self.number}
else:
return {'error': 'Attachment not found', 'name': self.number}
In python...
import time
import base64
printsock = xmlrpclib.ServerProxy('http://server:8069/xmlrpc/report')
model = 'account.invoice'
id_report = printsock.report(dbname, uid, pwd, model, ids, {'model': model, 'id': ids[0], 'report_type':'pdf'})
time.sleep(5)
state = False
attempt = 0
while not state:
report = printsock.report_get(dbname, uid, pwd, id_report)
state = report['state']
if not state:
time.sleep(1)
attempt += 1
if attempt>200:
print 'Printing aborted, too long delay !'
string_pdf = base64.decodestring(report['result'])
file_pdf = open('/tmp/file.pdf','w')
file_pdf.write(string_pdf)
file_pdf.close()