Can Someone Please Tell Me What This Code Does - python-3.x

import imaplib,time
class Mail():
def __init__(self):
self.user= 'USERNAME'
self.password= 'PASSWORD'
self.M = imaplib.IMAP4_SSL('imap.gmail.com', '993')
self.M.login(self.user, self.password)
def checkMail(self):
self.M.select()
self.unRead = self.M.search(None, 'UnSeen')
return len(self.unRead[1][0].split())
email = Mail()
while 1:
print ('Sending')
time.sleep(2)

You initialize a class called Mail that supposedly uses the imaplib library to check the unread messages of a gmail account. However, after you assign email to an instance of Mail, your while loop, which is responsible for the action in your code, is comprised of two events; a print and a time.sleep().
So your code essentially is a long way of printing 'Sending' every 2 seconds.
Running after commenting out the line email = Mail() due to invalid credentials
bash-3.2$ python foo.py
Sending
Sending
^CTraceback (most recent call last):
File "foo.py", line 21, in <module>
time.sleep(2)
KeyboardInterrupt
bash-3.2$

Related

Please , can you help me get rid of this error?

I am trying to create a code for a random password generator with python and flask. I have created both the front end and the backend yet every time i am trying to run it i get a json error:
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
this is my front end code:
import requests
import json
session=requests.session()
data={"letters":0,"symbols":0,"numbers":0}
header={"content-type": "application/json"}
print("Welcome to the PyPassword generator!")
while True:
data ["letters"]=input("how many lettres would you like in your password? > ")
data ["symbols"]=input("how many symbols would you like? > ")
data ["numbers"]=input("how many numbers would you like? > ")
print(data)
r=session.post("http://127.0.0.1:1337/api/PyPassword_generator", data=json.dumps(data), headers=header)
if r:
break
json_data=r.json()
print(json_data)
EDIT: Ading the response from the server component
Traceback (most recent call last):
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\requests\models.py", line 972, in json
return complexjson.loads(self.text, **kwargs)
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\simplejson\__init__.py", line 525, in loads
return _default_decoder.decode(s)
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\simplejson\decoder.py", line 370, in decode
obj, end = self.raw_decode(s)
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\simplejson\decoder.py", line 400, in raw_decode
return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\User\Downloads\client.py", line 19, in <module>
json_data = r.json()
File "C:\Users\User\PycharmProjects\pythonProject\venv\lib\site-packages\requests\models.py", line 976, in json
raise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
b'<!doctype html>\n<html lang=en>\n<title>405 Method Not Allowed</title>\n<h1>Method Not Allowed</h1>\n<p>The method is not allowed for the requested URL.</p>\n'
Process finished with exit code 1ode here
so this is the server code
from flask import Flask, request, session, jsonify,json
import random
class game:
def __init__(self,lettres,symbols,numbers):
self.letters=lettres
self.symbols=symbols
self.numbers=numbers
self.app = Flask("Shmuel Api server",static_url_path='')
self.app.secret_key="Secret"
#self.app.route('/api/ PyPassword_generator', methods=['Get',"Post"])
def PyPassword_generator():
print(request.data)
print(json.loads(request.data.decode("ascii")))
a=int(request.json["letters"])
b=int(request.json["symbols"])
c=int(request.json["numbers"])
password = self.test(a,b,c)
jsonify({f"your password is : {password}"})
def run(self):
debug=True
self.app.run(host='10.0.0.10', port='5000', debug=debug)
password_list=[]
for char in range(a):
password_list.append(random.choice(self.letters))
for char in range(b):
password_list.append(random.choice(self.symbols))
for char in range(c):
password_list.append(random.choice(self.numbers))
random.shuffle(password_list)
password="".join(password_list)
return password
mp=game(["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"],["0","1","2","3","4","5","6","7","8","9"],["!","#","$","%","&","(",")","*","+"])
mp.run()
and this is the response I get
* Serving Flask app 'Shmuel Api server' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://10.0.0.10:5000 (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 446-336-887
10.0.0.10 - - [11/Jun/2022 21:23:52] "POST /api/PyPassword_generator HTTP/1.1" 405 -
There's a space in the URL of the server component, and the methods must be in caps...
#self.app.route('/api/ PyPassword_generator', methods=['Get',"Post"])
should look like:
#self.app.route('/api/PyPassword_generator', methods=['GET',"POST"])
Defining Flask routes inside an object like this looks wrong though. I would probably simplify it:
from flask import Flask, request, session, jsonify,json
import random
app = Flask("__name__")
app.config['SECRET_KEY']='make me super secret'
#app.route('/api/PyPassword_generator', methods=['GET',"POST"])
def PyPassword_generator():
# print(request.data)
# print(json.loads(request.data.decode("ascii")))
try:
submitted_data = request.get_json()
a=int(submitted_data["letters"])
b=int(submitted_data["symbols"])
c=int(submitted_data["numbers"])
except ValueError: # Some issue with the input
return {'error': 'invalid input data'}, 400
password = generate_password(a,b,c)
return jsonify({'message': f"your password is : {password}"})
Then on the client end, simplify things, by using requests native json argument, which means you don't need to use the json.dumps or pass the headers either, as this arg automatically sets the Content-Type...
import requests
session=requests.session()
data={"letters":0,"symbols":0,"numbers":0}
print("Welcome to the PyPassword generator!")
while True:
data["letters"]=input("how many lettres would you like in your password? > ")
data["symbols"]=input("how many symbols would you like? > ")
data["numbers"]=input("how many numbers would you like? > ")
print(data)
r = session.post("http://127.0.0.1:5005/api/PyPassword_generator", json=data)
json_data=r.json()
print(json_data)
if r.ok:
break
Of course generating passwords comes with its own security considerations, and I assume this is just for learning python. Transmitting passwords over the wire comes with security considerations you should understand first.
With that in mind, instead of random.shuffle for this, perhaps investigate the python secrets module. Let's implement the generate_password function, and instead only work with the input a to set the length of the overall password. Using their example, you could have something like:
import secrets
import string
def generate_password(a,b,c):
alphabet = string.ascii_letters + string.digits + string.punctuation
password = ''.join(secrets.choice(alphabet) for i in range(a))
return password
Now this all works like:
Welcome to the PyPassword generator!
how many lettres would you like in your password? > 20
how many symbols would you like? > 1
how many numbers would you like? > 1
{'letters': '20', 'symbols': '1', 'numbers': '1'}
{'message': 'your password is : R#!o]KFnqk`,+Wg{JQ:#'}
Of course some obvious changes required on your part, but hope this helps.

How to work around problem with Python smtpd?

I want to make a small SMTP server for testing, using Python, so I was trying the server example code
https://pymotw.com/2/smtpd/
import smtpd
import asyncore
class CustomSMTPServer(smtpd.SMTPServer):
def process_message(self, peer, mailfrom, rcpttos, data):
print 'Receiving message from:', peer
print 'Message addressed from:', mailfrom
print 'Message addressed to :', rcpttos
print 'Message length :', len(data)
return
server = CustomSMTPServer(('127.0.0.1', 1025), None)
asyncore.loop()
Together with the example client code on that same page:
import smtplib
import email.utils
from email.mime.text import MIMEText
# Create the message
msg = MIMEText('This is the body of the message.')
msg['To'] = email.utils.formataddr(('Recipient', 'recipient#example.com'))
msg['From'] = email.utils.formataddr(('Author', 'author#example.com'))
msg['Subject'] = 'Simple test message'
server = smtplib.SMTP('127.0.0.1', 1025)
server.set_debuglevel(True) # show communication with the server
try:
server.sendmail('author#example.com', ['recipient#example.com'], msg.as_string())
finally:
server.quit()
However, when I try to run the client, I am getting the following on the server side:
error: uncaptured python exception, closing channel <smtpd.SMTPChannel connected 127.0.0.1:38634 at 0x7fe28a901490> (<class 'TypeError'>:process_message() got an unexpected keyword argument 'mail_options' [/root/Python-3.8.1/Lib/asyncore.py|read|83] [/root/Python-3.8.1/Lib/asyncore.py|handle_read_event|420] [/root/Python-3.8.1/Lib/asynchat.py|handle_read|171] [/root/Python-3.8.1/Lib/smtpd.py|found_terminator|386])
^CTraceback (most recent call last):
File "./mysmtpd.py", line 18, in <module>
asyncore.loop()
File "/root/Python-3.8.1/Lib/asyncore.py", line 203, in loop
poll_fun(timeout, map)
File "/root/Python-3.8.1/Lib/asyncore.py", line 144, in poll
r, w, e = select.select(r, w, e, timeout)
KeyboardInterrupt
Then I found this Issue page:
https://bugs.python.org/issue35837
and I think that that is the problem I've been running into.
That issue hasn't been fixed yet, so I was wondering if, meantime, is there something that I can modify in the example client code that would get around the problem that is described in that issue?
Thanks,
Jim
Add an mail_options=None in your process_message() function.
Just for reference, do the same with the rcpt_options argument.
Ref: https://docs.python.org/3/library/smtpd.html?highlight=process_message#smtpd.SMTPServer.process_message
The error seems to appear
in the line with def process_message(self, peer, mailfrom, rcpttos, data):.
You can replace it with def process_message(self, peer, mailfrom, rcpttos, data,**my_krargs):

Python3 SMTP 'Connection unexpectedly closed'

Could somebody please tell me why I am getting a SMTPServerDisconnected("Connection unexpectedly closed") error from the following code?
import smtplib
from string import Template
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
MY_ADDRESS = '---'
PASSWORD = '---'
def get_contacts(filename):
"""
Return two lists names, emails containing names and email
addresses
read from a file specified by filename.
"""
names = []
emails = []
with open(filename, mode='r', encoding='utf-8') as contacts_file:
for a_contact in contacts_file:
names.append(a_contact.split()[0])
emails.append(a_contact.split()[1])
return names, emails
def read_template(filename):
"""
Returns a Template object comprising the contents of the
file specified by filename.
"""
with open(filename, 'r', encoding='utf-8') as template_file:
template_file_content = template_file.read()
return Template(template_file_content)
def main():
names, emails = get_contacts('contacts.txt') # read contacts
message_template = read_template('message.txt')
# set up the SMTP server
s = smtplib.SMTP('smtp.gmail.com', 465)
s.ehlo()
s.starttls()
s.login(MY_ADDRESS, PASSWORD)
# For each contact, send the email:
for name, email in zip(names, emails):
msg = MIMEMultipart() # create a message
# add in the actual person name to the message template
message =
message_template.substitute(PERSON_NAME=name.title())
# Prints out the message body for our sake
print(message)
# setup the parameters of the message
msg['From']=MY_ADDRESS
msg['To']=email
msg['Subject']="This is TEST"
# add in the message body
msg.attach(MIMEText(message, 'plain'))
# send the message via the server set up earlier.
s.send_message(msg)
del msg
# Terminate the SMTP session and close the connection
s.quit()
if __name__ == '__main__':
main()
Obviously when I run the code my address and password is filled in.
The traceback I get from this when running in terminal is:
Traceback (most recent call last):
File "emailAlert2.py", line 71, in
main()
File "emailAlert2.py", line 40, in main
s = smtplib.SMTP('smtp.gmail.com', 465)
File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 251, in init
(code, msg) = self.connect(host, port)
File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 338, in connect
(code, msg) = self.getreply()
File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/smtplib.py", line 394, in getreply
raise SMTPServerDisconnected("Connection unexpectedly closed")
smtplib.SMTPServerDisconnected: Connection unexpectedly closed
Thanks
The Google Gmail server is hanging up on your (dropping your connection attempt).
Provided that you have enabled third party access (link) to your Gmail account, change your code as follows:
s = smtplib.SMTP('smtp.gmail.com', 465)
s.ehlo()
s.starttls()
s.login(MY_ADDRESS, PASSWORD)
Change to this:
s = smtplib.SMTP_SSL('smtp.gmail.com', 465)
s.ehlo()
s.login(MY_ADDRESS, PASSWORD)
The reason for the hang up is that you are creating a connection using an unencrypted method (smtplib.SMTP()). Google is expecting that you are connecting using SMTPS which requires SSL.
Try port number 587 instead of port 465 in s = smtplib.SMTP('smtp.gmail.com', 465)
Probably you may need to come up with App password instead of your default password - Check this out - https://support.google.com/accounts/answer/185833

Appium & Python: How to move to another app?

I am making a testing bot with Python and Appium.
I need to extract the email of a button. I tired to extract href, but button are obviously something else than in smartphone applications.
So I click on this button which open my gmail with the New message window and the email in the "To" field.
SO I investigate and I could find only 1 tutoriel in Java :-(.
I found something else. SOmeone propose to instantiate new driver:
driver2 = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps2)
print("we setup driver2")
email = driver2.find_element_by_id("com.google.android.gm:id/to").text
But it stop immediately the browser. ANd Pycharm displayed this error:
Error Traceback (most recent call last): File
"C:\Users\Nino\AppData\Local\Programs\Python\Python37\lib\unittest\case.py",
line 59, in testPartExecutor
yield File "C:\Users\Nino\AppData\Local\Programs\Python\Python37\lib\unittest\case.py",
line 628, in run
testMethod() File "C:\Users\Nino\PycharmProjects\mybot\mybot_mybot.py", line 92, in
test_scrap_email
email = driver2.find_element_by_id("com.google.android.gm:id/to").text File
"C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py",
line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_) File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\appium\webdriver\webdriver.py",
line 276, in find_element
'value': value})['value'] File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\selenium\webdriver\remote\webdriver.py",
line 321, in execute
self.error_handler.check_response(response) File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\appium\webdriver\errorhandler.py",
line 29, in check_response
raise wde File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\appium\webdriver\errorhandler.py",
line 24, in check_response
super(MobileErrorHandler, self).check_response(response) File "C:\Users\Nino\PycharmProjects\mybot\venv\lib\site-packages\selenium\webdriver\remote\errorhandler.py",
line 242, in check_response
raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: An element
could not be located on the page using the given search parameters.
I am using unittest which instantiate one driver going to 1 app (where there si the email button), then I instantiate in the middle of the code a new driver.
But it bugs. And Icannot find anywhere an article or forum question about switching from 1 app to other app.
I prefer to let you te code of my bot:
from datetime import time
from time import sleep
from appium import webdriver
import unittest
from selenium.webdriver.common.by import By
class apptotest1(unittest.TestCase):
def setUp(self):
desired_caps = {}
desired_caps['platformName']='Android'
desired_caps['platformVersion']='6.0'
desired_caps['deviceName']='S6S5IN3G'
desired_caps['noReset']='true'
desired_caps['appPackage']='com.apptotest1'
desired_caps['appActivity']=' com.apptotest1.android/com.apptotest1.android.activity.MainTabActivity'
self.driver = webdriver.Remote('http://localhost:4723/wd/hub',desired_caps)
#self.driver = webdriver.Remote('http://0.0.0.0:4723/wd/hub',desired_caps)
def tearDown(self):
self.driver.quit()
def test_scrap_email(self):
search_button = self.driver.find_element(By.XPATH,"//android.widget.ImageView[#bounds='[126,800][162,836]']")
#search_button = self.driver.find_element(By.XPATH ("//android.widget.ImageView[#content-desc='Rechercher et explorer']"))
if search_button:
print("search_button was found!")
search_button.click()
else:
print("search_button was not found :-(")
search_field = self.driver.find_element_by_id('com.apptotest1.android:id/action_bar_search_edit_text')
search_field.send_keys('marketing')
users_button = self.driver.find_element_by_id('com.apptotest1.android:id/tab_button_fallback_icon')
if users_button:
print("users_button was found!")
users_button.click()
else:
print("users_button was not found :-(")
users_button2 = self.driver.find_element(By.XPATH, "//android.widget.ImageView[#bounds='[162,123][198,159]']")
if users_button2:
print("users_button2 was found!")
users_button2.click()
else:
print("users_button2 was not found :-(")
sleep(5)
profile_test = self.driver.find_elements_by_id("com.apptotest1.android:id/row_search_user_username")[1]
if profile_test:
print("profile_test was found!")
profile_test.click()
else:
print("profile_test was not found :-(")
sleep(5)
button_email = self.driver.find_element(By.XPATH,"//android.widget.TextView[#text='Adresse e-mail']")
if button_email:
print("button_email was found!")
button_text = button_email.text
print("button_text is :" + str(button_text))
button_email.click()
else:
print("button_email was not found :-(")
desired_caps2 = {}
desired_caps2['platformName'] = 'Android'
desired_caps2['platformVersion'] = '6.0'
desired_caps2['deviceName'] = 'S6S5IN3G'
desired_caps2['noReset'] = 'true'
desired_caps2['appPackage'] = 'com.google.android.gm'
desired_caps2['appActivity'] = ' com.google.android.gm.ComposeActivityGmailExternal'
driver2 = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps2)
print("we setup driver2")
email = driver2.find_element_by_id("com.google.android.gm:id/to").text
sleep(10)
if email:
print("email was found!")
print("Es eso que querias :-) =>" + str(email))
else:
print("Email was not found :-(")
sleep(5)
if __name__ == '__main__':
suite = unittest.Testloader().loadTestsFromTestCase(apptotest1)
unittest.TextTestRunner(verbosity=1).run(suite)
Does anyone can help me please?
It looks like you're looking for start_activity function
The driver.start_activity method opens arbitrary activities on a device. If the activity is not part of the application under test, it will also launch the activity's application.
driver.start_activity('com.foo.app', '.MyActivity')
This way you should be able to switch between applications within the bounds of the same webdriver instance
You might also find Launch command useful as it is cross-platform approach allowing kicking off any installed application. The command is available via SeeTest Appium Extension.
It seems like you just need switch context, you facing web in gmail, try :
driver2 = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps2)
print("we setup driver2")
driver2.switch_to.context('WEBVIEW_1')
email = driver2.find_element_by_id("com.google.android.gm:id/to").text
Or
# switch to webview
webview = driver.contexts.last
driver.switch_to.context(webview)
And please try without new initilize driver2
Please read this reference and this.

Logging in as user using discord.py

I am trying to make some simple program, showing received messages through the terminal. Now I am trying to ask the user for their email address and password for the login, but some errors occur, which I do not quite understand. This is what my code looks like:
import discord
class DiscordClient(discord.Client):
def __init__(self, *args, **kwargs):
discord.Client.__init__(self, **kwargs)
async def on_ready(self):
print('Success!')
if __name__ == '__main__':
dc = DiscordClient()
dc.login(input('email : '), input('password : '), bot=False)
dc.run()
and the error is:
Traceback (most recent call last):
File "[...]/Main.py", line 16, in <module>
dc.run()
File "[...]/lib/python3.6/site-packages/discord/client.py", line 519, in run
self.loop.run_until_complete(self.start(*args, **kwargs))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/asyncio/base_events.py", line 466, in run_until_complete
return future.result()
File "[...]/lib/python3.6/site-packages/discord/client.py", line 490, in start
yield from self.login(*args, **kwargs)
File "[...]/lib/python3.6/site-packages/discord/client.py", line 418, in login
raise TypeError('login() takes 1 or 2 positional arguments but {} were given'.format(n))
TypeError: login() takes 1 or 2 positional arguments but 0 were given
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x103881fd0>
So, what am I doing wrong, or what should code look like? All I was doing was write an on_message() and some basic commands like send_message().
client.login is a coroutine so it should be (untested) :
await dc.login(input('email : '), input('password : '), bot=False)
Note that in this case, bot parameter is not needed.
However, to use client.login, you need to use the client loop. To avoid that, you can simply do:
dc.run(email, password)
Which will both login and connect and then start the loop.
After that you can (in the on_ready function) get a desired server from dc.servers and a suitable channel to send there, for example, a 'Hello message' with dc.send_message.
When you are done with the connection, do self.close() from within the DiscordClient class.
Working example for Python 3.4 (replace keywords as necessary for Python 3.6)
import discord
import asyncio
import datetime
class DiscordClient(discord.Client):
def __init__(self, *args, **kwargs):
discord.Client.__init__(self, **kwargs)
#asyncio.coroutine
def on_ready(self):
servers = list(self.servers)
for server in servers:
if server.name == 'My server':
break
for channel in server.channels:
if channel.name == 'general':
break
now = datetime.datetime.now()
yield from self.send_message(channel, 'Api Success! at ' + str(now))
print('Success!')
yield from self.close()
if __name__ == '__main__':
dc = DiscordClient()
email = input('email : ')
password = input('password : ')
dc.run(email, password)

Resources