How to add an exception in pyautogui - python

I created a code using pyautogui to send messages automatically in whatsapp, but there is a problem, I'm using a purchased database so some of the phones don't exist or aren't in whatsapp, how could I add this exception in pyautogui? when the phone exists, the program runs normally and clicks on starting the conversation as programmed, but when it does not exist, instead of sending the programmed message to the contact, it sends it to the group where the contacts are
import pyautogui
import pyperclip
import time
import random
import pygame
pyautogui.pause = 2
text = ("""message
message
message """)
pyautogui.press('win')
pyautogui.write('brave')
pyautogui.press('enter')
time.sleep(2)
pyautogui.hotkey('ctrl','t')
pyperclip.copy('https://web.whatsapp.com/')
pyautogui.hotkey('ctrl', 'v')
pyautogui.press('enter')
time.sleep(10)
x = 1513
y = 152
yy = 183
for i in range(40):
#enter on the group
pyautogui.click(x=339, y=383)
#clicking into the contact
pyautogui.click(x=x, y=y)
time.sleep(1)
pyautogui.click(x=x, y=y)
time.sleep(random.uniform(1.2, 3.5))
pyautogui.click(x=x, y=y)
#the box with option of start a chat appears
pyautogui.click(x=1400, y=yy)
time.sleep(random.uniform(0.7, 1.8))
#click on the chat
pyautogui.click(x=788, y=966)
time.sleep(random.uniform(2.0, 3.8))
pyperclip.copy(text)
pyautogui.hotkey('ctrl','v')
time.sleep(random.uniform(2.0, 4.0))
pyautogui.press('enter')
time.sleep(random.uniform(4.5, 10.3))
y += 17
yy += 18
if i == 39:
pygame.init()
pygame.mixer.music.load("beet.mp3")
pygame.mixer.music.play()
Im expecting to find a answer to ignore when the phone does not exist and just proceed with the looping with the contacts below (with the y += 17, yy +=18)

You can't do this with pyautogui library since it's just a mouse/keyboard simulation library.
I would try to accomplish this using some libraries that include
text recognition functions such as OpenCv or TesseractOCR, google them.

Related

python-vlc switching playback media between launches

I'm trying to set up a system where my start-screen video loops until 1 of 2 buttons is pressed (GPIO buttons).
Then, the playback changes to either a video with subtitles or no-subtitles.
Once that has finished its play-through, it reverts back to the splash screen video.
I have additional tickers in here just to count the number of play-throughs per day for analytics. My Test device also only has 1 button hooked up which is why GPIO 18 is never used. Implementation will be identical to GPIO 17's, so once one is working the other won't be hard to match up.
Problem
When I launch the script, the media played is not always splash. The script also closes the window at the end of playback, and opens a new one to play the media. I believe this may be due to not establishing an xwindow (for raspberry pi).
Any advice?
#Vars
GPIO.setmode(GPIO.BCM)
GPIO.setup(17,GPIO.IN)
GPIO.setup(18,GPIO.IN)
update = True #Update to false to exit
def Main():
# Setup logs
print(date.today())
# Media Paths
path = "/home/pi/Videos/"
nosubs = path+"Content-NoSubs.mp4"
subs = path+"Content-Subtitles.mp4"
splash = path+"StartScreen.mp4"
Instance = vlc.Instance("-f")
playlist = set([splash,subs,nosubs])
url = [str(splash),str(subs),str(nosubs)] #Yes, this looks pretty redundant. Hopefully it's not.
#Setup the player
player = Instance.media_list_player_new()
Media = Instance.media_new(url[1])
Media_list = Instance.media_list_new(playlist)
Media.get_mrl()
player.set_media_list(Media_list)
playerState = {'State.NothingSpecial',
'State.Opening',
'State.Buffering',
'State.Playing',
'State.Paused',
'State.Stopped',
'State.Ended',
'State.Error'}
subsPlayed = 0
nosubsPlayed = 0
active = 0
playingMedia = 0
while update:
input = GPIO.input(17)
state = str(player.get_state())
if(state == playerState[0]):
player.play_item_at_index(0)
player.set_playback_mode(2)
if(state == playerState[7]):
player.play_item_at_index(0)
playingMedia = 0
if input == 1 and playingMedia == 0:
playingMedia = 1
player.play_item_at_index(1)
active +=1
nosubsPlayed +=1
print(playingMedia)
with open(str(date.today()))+'.txt','w' as file:
file.write("Active Views: " + active)
file.write("SubsPlayed: " + subsPlayed)
file.write("No Subs Played: " + nosubsPlayed)
Main()
So I figured out the solution, but not the problem's origin.
# Make my media paths into vlc.Media Objects
nosubs = vlc.Media(path+"Content-NoSubs.mp4")
subs = vlc.Media(path+"Content-Subtitles.mp4")
splash = vlc.Media(path+"SplashScreen.mp4")
#Setup the player
player = Instance.media_list_player_new()
Media_list = Instance.media_list_new()
Media_list.add_media(splash)
Media_list.add_media(subs)
Media_list.add_media(nosubs)
player.set_media_list(Media_list)
Media_list.lock()
Setting up each of the media by name in my list helps by switching the play function from play_item_at_index(int) to play_item(media)
Still not sure why it was kind of randomizing. My guess was that it changed the position of media in the list based on play through.
My next step will be to adjust this to work off of media_player and embedding playback into a tkinter window.

Detect key pressed in a loop

I am trying to detect the key pressed by a user in order to reset a variable for my program, a basic application to detect a barcode, which is running inside a While true
I have tried using keyboard library like in the first solution suggested here
import keyboard # using module keyboard
while True:
if keyboard.is_pressed('q'): # if key 'q' is pressed
print('You Pressed A Key!')
...
but I m getting an error You must be root to use this library on Linux. I am not sure if that it means is not possible to use this approach in my case because I m ruining the program on Raspberry Pi OS.
I also tried the second approach ( from the same link) using pynput.keyboard but as the author says, it does not perform well when using inside a loop. the application waits for a key to be pressed.
Edit : More Info
from pyzbar import pyzbar
import datetime
import imutils
import time
from imutils.video import VideoStream
import pika
import json
from pynput.keyboard import Key, Listener
connection = pika.BlockingConnection(
pika.ConnectionParameters(host="----",
virtual_host="----",
credentials=pika.credentials.PlainCredentials(
"---", "---")
))
channel = connection.channel()
channel.queue_declare(queue='barcode_queue')
print("[INFO] Connection Started ...")
vs = VideoStream(usePiCamera=True).start()
print("[INFO] starting video stream...")
time.sleep(2.0)
userWebsocket = None
while True:
# this is what I want to achive
# key = Get the key pressed
# if key == 'q' then userWebsocket = None
frame = vs.read()
frame = imutils.resize(frame, width=400)
barcodes = pyzbar.decode(frame)
for barcode in barcodes:
barcodeData = barcode.data.decode("utf-8")
barcodeType = barcode.type
if barcodeType == 'QRCODE':
decodedBarcode = json.loads(barcodeData)
print(decodedBarcode)
print(decodedBarcode['name'])
userWebsocket = decodedBarcode['id']
else:
print(datetime.datetime.now(), barcodeData, barcodeType)
if (userWebsocket is None):
print("please login before")
else:
sentObj = {"socket": userWebsocket, "barcode": barcodeData}
jsonSentObj = json.dumps(sentObj)
channel.basic_publish(exchange='', routing_key='barcode_queue', body=jsonSentObj)
time.sleep(5)
vs.stop()
What I want to achieve is to "sign-out" the user when he presses a certain key.

Whatsapp Bot Problem when identifying any onLocateScreen object with Python

import pyautogui as pt
from time import sleep
import pyperclip
import random
sleep(3)
position1 = pt.locateOnScreen("whatsapp/smile.png", confidence=.6)
x = position1[0]
y = position1[1]
# Gets Message
def get_message():
global x, y
position = pt.locateOnScreen("whatsapp/smile.png", confidence=.6)
x = position[0]
y = position[1]
pt.moveTo(x, y, duration=.05)
get_message()
When I try to run this code and open Whatsapp desktop, it fails and shows an error message like
OSError: Failed to read whatsapp/smile.png because file is missing, has improper permissions, or is an unsupported or invalid format
The title and the image format are correct. I've checked it many times. Any other suggestions on what might be the issue here?

How to create a single widget in the same GUI with tkinter in python

I'm trying to create a GUI that has two buttons: One checks whether the user has provided all the required inputs while the other runs a backend script. My problem is that this GUI will run for as long as the user wants to perform the backend task. The problem is: every time the user clicks on the 'check' button, another 'run' button is created right bellow the one last created. I need the 'run' button to be created at the same position every time the check button is clicked. I'm a newbie in python, btw. I'll appreciate if anyone can tell me if I got it all wrong. Thanks!
def verifica():
fluxo=vfluxo.get()
permissoes=vpermissoes.get()
results = vresults.get()
if fluxo==2:
label4 = Label(setup_window, text='Quantas tentativas (1-20)?')
label4.pack()
tentativas = Entry(setup_window)
tentativas.pack()
else:
label5 = Label(setup_window, text='Ready!')
label5.pack()
def bot_setup():
if fluxo==2:
num_tentativas = tentativas.get()
if num_tentativas == '' or int(num_tentativas) > 20:
num_tentativas=0
messagebox.showerror('ERRO!','Digite um tamanho de lote vĂ¡lido (1 a 20)')
else:
num_tentativas=1
setup = {
'tipo_operacao':fluxo,
'permissoes':permissoes,
'mostrarnofim':results,
'tamanho_lote':int(num_tentativas)
}
return setup
comecar = Button(text='Run', command = bot_setup)
comecar.pack()
verificar = Button(text='Check', command = verifica)
verificar.pack()

How to play a sound when a value increases by 1 between loops? What does the code look like that identifies the increment by 1?

I have designed and created a program using Python 3 that reads unread messages in my Gmail inbox under two labels.
By using tkinter I have two lovely boxes that display the total messages in each label. One for sales of one particular product and the other for another.
They use the update loop to recheck each label every few seconds.
Then after the business day, I use a cleanup script in Gmail that flushes the inboxes two labels.
The program is for use on my team's sales floor. They can see daily, the number of sales, and get a real-time readout to the success of certain marketing campaigns. It has done wonders for morale.
Now I would like to implement some sounds when sales go up. A cliche bell ring, a "chhaaaching" perhaps, you get the drift.
So, I am currently tackling with my limited knowledge and have searched all throughout StackOverflow and other sites for an answer. My guess is that I need something like the following...
"if an integer value changes on the next loop from it's previous value, by an increment of 1 play soundA, or, play soundB if that value decreases by 1."
I can't for the life of me figure out what would be the term for 'increases by 1', I am also clueless on how to attach a sound to any changes made to the integer on the proceeding loop. Help!!
If I wasn't clear enough, I am more than happy to explain and go into this further.
Thank you so much guys.
Here is my code as it stands so far...
#! /usr/bin/python3
import imaplib
import email
import tkinter as tk
WIDTH = 1000
HEIGHT = 100
def update():
mail=imaplib.IMAP4_SSL('imap.gmail.com',993)
mail.login('email#gmail.com','MyPassword')
mail.select("Submissions")
typ, messageIDs = mail.search(None, "UNSEEN")
FirstDataSetSUBS = str(messageIDs[0], encoding='utf8')
if FirstDataSetSUBS == '':
info1['text'] = 'no submissions'
else:
SecondDataSetSUBS = FirstDataSetSUBS.split(" ")
nosubs = len(SecondDataSetSUBS)
nosubs = int(nosubs)
info1['text'] = '{} submission[s]'.format(nosubs)
subs.after(1000, update)
def update_2():
mail=imaplib.IMAP4_SSL('imap.gmail.com',993)
mail.login('email#gmail.com','MyPassword')
mail.select("Memberships")
typ, messageIDs = mail.search(None, "UNSEEN")
FirstDataSetMSGS = str(messageIDs[0], encoding='utf8')
if FirstDataSetMSGS == '':
info2['text'] = 'no memberships'
else:
SecondDataSetMSGS = FirstDataSetMSGS.split(" ")
memberships = len(SecondDataSetMSGS)
memberships = int(memberships)
info2['text'] = '{} membership[s]'.format(memberships)
membs.after(1000, update_2)
membs = tk.Tk()
subs = tk.Tk()
membs.title('memberships counter')
membs.configure(background="black")
subs.title('submissions counter')
subs.configure(background="black")
x = (subs.winfo_screenwidth()//5) - (WIDTH//5)
y = (subs.winfo_screenheight()//5) - (HEIGHT//5)
subs.geometry('{}x{}+{}+{}'.format(WIDTH, HEIGHT, x, y))
info1 = tk.Label(subs, text='nothing to display', bg="black", fg="green", font="Lucida_Console 40")
info1.pack()
x = (membs.winfo_screenwidth()//2) - (WIDTH//2)
y = (membs.winfo_screenheight()//2) - (HEIGHT//2)
membs.geometry('{}x{}+{}+{}'.format(WIDTH, HEIGHT, x, y))
info2 = tk.Label(membs, text='nothing to display', bg="black", fg="red", font="Lucida_Console 40")
info2.pack()
update()
update_2()
membs.mainloop
subs.mainloop()
for playing audio you can use pyaudio module
in ubuntu, install by pip3 install pyaudio include sudo if required
import pygame
pygame.init()
increased=0
inc_music=pygame.mixer.music
dec_music=pygame.mixer.music
inc_music.load("/home/pratik/Documents/pos.wav")
dec_music.load("/home/pratik/Documents/neg.wav")
def get_inc():
global increased
a=increased
return a
def pl():
global inc_music
global dec_music
while True:
increased=get_inc()
if increased == 1:
inc_music.play()
increased=increased-1
elif increased == -1:
dec_music.play()
increased=increased+1
here increased is a global variable. Make sure whenever your sales is increased it is set to +1 and whenever it is decreased it is set to -1 and call pl function in a separate thread by using threading library in the background. Since, it is a forever loop it will continuosly run in background and ring the bells.
from threading import Thread
th=Thread(target=pl)
th.setDaemon(True)
th.start()
While writing the above I assumed at a moment there is either an increase or a decrease in sales, both dont occour simultaneously. If they do, use another global variable decreased which is also initialised with 0 and decreased by -1 each time decrease in sales. And return both of them from get_inc() .
Below code produces a label that gets updated randomly, and plays the sound files located in "C:\Windows\Media\" based on the change:
import tkinter as tk
import random
from playsound import playsound
def sound(is_positive=True):
if is_positive:
playsound(r"C:\Windows\Media\chimes.wav", False)
else:
playsound(r"C:\Windows\Media\chord.wav", False)
def random_update():
_old = label['text']
_new = random.randint(1, 100)
if _new > _old: # use (_new - _old) == 1 for checking
sound() # increment of 1 exclusively
elif _new < _old: # use (_new - _old) == -1 for checking
sound(False) # decrement of 1 exclusively
label['text'] = _new
label.after(2000, random_update)
if __name__ == '__main__':
root = tk.Tk()
label = tk.Label(root, text=1)
label.after(2000, random_update)
label.pack()
root.mainloop()
playsound is not a built-in package so it needs to be installed separately. You can install using:
pip install playsound
or:
python -m pip install playsound
in the command prompt on windows.

Categories