Command not executed on if statement being true - python

So I'm writing a simple program in Python that checks active window ID and in this program I have an if statement inside a while True loop that checks if the active window ID matches the expected window ID.
Here's the code:
import os, subprocess
def get_window_id():
output = subprocess.check_output("xprop -root | grep \"window id\"", shell=True)
get_window_id.result = {}
for row in output.split(b"\n"):
if b": " in row:
key, value = row.split(b": ")
get_window_id.result[key.strip(b"window id # ")] = value.strip()
while True:
get_window_id()
print(get_window_id.result[b"_NET_ACTIVE_WINDOW(WINDOW)"].strip(b"b'window id # "))
if get_window_id.result[b"_NET_ACTIVE_WINDOW(WINDOW)"].strip(b"b'window id # ") != "b'0x3000003'":
os.system("kill -STOP $(pgrep mpv)")
else:
os.system("kill -CONT $(pgrep mpv)")
When the active window ID doesn't match the expected one, the block of code that corresponds to that condition executes, but when the active window ID matches the expected one, the block of code that corresponds to that condition doesn't execute. I obviously want that block of code to execute.
As you can see, I'm not the best at Python and asking for help but I hope that this is enough for somebody to help. If not I can always provide more information :)
And sorry if the title and/or body of the question are not clear. It's currently 2AM and I've been trying to do this all day.
Thanks in advance.

YES! I did it! Just needed some sleep and a little bit more searching, but basically what I needed to do is get rid of those bs before the strings and to do that I needed to add encoding=utf8 to the subprocess.check_output line and delete the bs and it worked!
Code after the change:
import os, subprocess
def get_window_id():
output = subprocess.check_output("xprop -root | grep \"window id\"", shell=True, encoding="utf8")
get_window_id.result = {}
for row in output.split("\n"):
if ": " in row:
key, value = row.split(": ")
get_window_id.result[key.strip("window id # ")] = value.strip()
while True:
get_window_id()
print(get_window_id.result["_NET_ACTIVE_WINDOW(WINDOW)"].strip("'window id # "))
if get_window_id.result["_NET_ACTIVE_WINDOW(WINDOW)"].strip("'window id # ") != "0x3000003":
os.system("kill -STOP $(pgrep mpv)")
else:
os.system("kill -CONT $(pgrep mpv)")

Related

How can I overwrite a text after it's printed a few lines before?

I want to make a task/time manager. I want the list of tasks to be at the top and a question to add a new task if the user wants, but the problem is that I can't keep my to-do list in the top and I can't make it updated. What should I do?
This is my code, this is the form I want and the code I've written:
TASKS:(I want this to be updated)
1)--------
2)----------
3)----------
|
v
do you want to add a task(YES/NO):
when do you want to start the task (HOUR:MINUTE):
task_num = 0
k = False
print("YOUR TASKS")
if k == True:
print("\r", tasks)
print("tasks" + ":" + str(task_num), "\n\n")
active = True
while active:
add_task = input("do you want to add a task(YES/NO):",)
if add_task != 'YES':
active = False
else:
k = True
start_time = input("when do you want to start the task (HOUR:MINUTE):")
end_time = input("when do you want to complete it:")
task_name = input("what do you want to call it:")
start_h, start_m = start_time.split(":")
end_h, end_m = end_time.split(":")
duration = str(abs(int(end_h) - int(start_h))) + ":" + str(abs(int(end_m) - int(start_m)))
task = {"task name": task_name, "start time": start_time, "end time": end_time, "duration": duration}
task_num += 1
tasks[task_num] = task
for key in tasks.keys():
task_key = tasks[key]
print(key,end=")")
for key1 in task_key.keys():
print(key1, ":", task_key[key1], end='|',)
print('\n')
On POSIX systems clear -x command works like a charm. It preserves the current scroll buffer and produces almost zero flickering. Combine that with hiding the cursor, ah it is marvelous.
import sys
import subprocess
try:
sys.stdout.write('\033[?25l') # hide cursor
subprocess.run(['clear', '-x'])
finally:
sys.stdout.write('\033[?25h') # show cursor
sys.stdout.flush()
On Windows, on the other hand, you'll probably need colorama package installed and initialized.See https://github.com/tartley/colorama
On Windows cmd:
import sys
import shutil
height = shutil.get_terminal_size().lines
h = height * '\n'
# move cursor down and up.
sys.stdout.write(f'{h}\033[{height}A')
sys.stdout.flush()
On Windows Terminal and other modern terminal emulators:
import sys
import shutil
height = shutil.get_terminal_size().lines
# clear the screen with the ANSI sequence.
sys.stdout.write((height - 1) * '\n' + '\033[2J')
sys.stdout.flush()
Play with them and see what works for you.

Python,Shell: How to extract data and store in a iterable varible(specifically in list)?

I am working on my own project. In which these steps have to be performed:
Connect to remote server.
Get pid, process name, cpu usage, swap memory usage by each running process on remote server daily on some specific time(say at 4'0 clock).
I have to compare every day's result with previous day's result (e.g. day1-pid with day2 pid and day1 process name with day2 process name etc.)
So far I have done up to step-2. Now I want to know that how to extract the pid, process name, cpu usage, swap memory usage from remote server and store it in some iterable variable. So that I can compare it for checking memory spike?
Any other way apart from my idea will be appreciable.
My code sample is like this:
import paramiko
import re
import psutil
class ShellHandler:
def __init__(self, host, user, psw):
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(host, username=user, password=psw, port=22)
channel = self.ssh.invoke_shell()
self.stdin = channel.makefile('wb')
self.stdout = channel.makefile('r')
def __del__(self):
self.ssh.close()
#staticmethod
def _print_exec_out(cmd, out_buf, err_buf, exit_status):
print('command executed: {}'.format(cmd))
print('STDOUT:')
for line in out_buf:
print(line, end="")
print('end of STDOUT')
print('STDERR:')
for line in err_buf:
print(line, end="")
print('end of STDERR')
print('finished with exit status: {}'.format(exit_status))
print('------------------------------------')
#print(psutil.pids())
pass
def execute(self, cmd):
"""
:param cmd: the command to be executed on the remote computer
:examples: execute('ls')
execute('finger')
execute('cd folder_name')
"""
cmd = cmd.strip('\n')
self.stdin.write(cmd + '\n')
finish = 'end of stdOUT buffer. finished with exit status'
echo_cmd = 'echo {} $?'.format(finish)
self.stdin.write(echo_cmd + '\n')
shin = self.stdin
self.stdin.flush()
shout = []
sherr = []
exit_status = 0
for line in self.stdout:
if str(line).startswith(cmd) or str(line).startswith(echo_cmd):
# up for now filled with shell junk from stdin
shout = []
elif str(line).startswith(finish):
# our finish command ends with the exit status
exit_status = int(str(line).rsplit(maxsplit=1)[1])
if exit_status:
# stderr is combined with stdout.
# thus, swap sherr with shout in a case of failure.
sherr = shout
shout = []
break
else:
# get rid of 'coloring and formatting' special characters
shout.append(re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[#-~]').sub('', line).replace('\b', '').replace('\r', ''))
# first and last lines of shout/sherr contain a prompt
if shout and echo_cmd in shout[-1]:
shout.pop()
if shout and cmd in shout[0]:
shout.pop(0)
if sherr and echo_cmd in sherr[-1]:
sherr.pop()
if sherr and cmd in sherr[0]:
sherr.pop(0)
self._print_exec_out(cmd=cmd, out_buf=shout, err_buf=sherr, exit_status=exit_status)
return shin, shout, sherr
obj=ShellHandler('Servername','username','password')
pID=[]
## I want this(pid, cmd, swap memory) to store in a varible which would be iterable.
pID=ShellHandler.execute(obj,"ps -eo pid,cmd,lstart,%mem,%cpu|awk '{print $1}'")
print(pID[0])##---------------------------------Problem not giving any output.
Your ShellHandler's execute method returns three items, the first of which is the input you sent to it.
You should probably call it directly like this, anyway:
obj = ShellHandler('Servername','username','password')
in, out, err = obj.execute("ps -eo pid,lstart,%mem,%cpu,cmd")
for line in out.split('\n'):
pid, lstartwd, lstartmo, lstartdd, lstartm, lstartyy, mem, cpu, cmd = line.split(None, 8)
I moved cmd last because it might contain spaces. The lstart value also contains multiple space-separated fields. Here's what the output looks like in Debian:
19626 Tue Jan 15 15:03:57 2019 0.0 0.0 less filename
There are many questions about how to parse ps output in more detail; I'll refer you to them for figuring out how to handle the results from split exactly.
Splitting out the output of ps using Python
Is there any way to get ps output programmatically?
ps aux command should have all the info you need (pid, process name, cpu, memory)

How to watch tasklist for running tasks

I've been dealing with this for a while. I don't think I can find an easy solution. What I want to know is how many hours I play games.
Why does printing result_1 return 0 sometimes and 1 other times? Why doesn't it return "No tasks are running..." or show me the running task?
import subprocess
from time import *
from datetime import *
command_1 = "TASKLIST /FI \"IMAGENAME eq Application-steam*\"" #Code for finding the "Banished" game
no_task_respond_0 = "INFO: No tasks are running which match the specified criteria."
while True:
the_time = datetime.now()
result_1 = subprocess.call(command_1, shell=True) # running this code prints the result whether i want it or not
open_file = open("watcher.txt","w")
current_task_file = open_file.write(str(result_1))
print(current_task_file,"Inside of Current task FILE!!")
if str(current_task_file) == str(no_task_respond_0): #If no games are running then continue
continue
else: #If the game started then note the time
date_file = open("datefile.txt","a")
date_watcher = date_file.write(str(the_time)+"\n")
sleep(4)
When I close the game, this is the result that it returns:
**INFO: No tasks are running which match the specified criteria.**
**1 Inside of Current Task FILE!!**
This is the output while the game is running:
Image Name PID Session Name Session# Mem Usage
========================= ======== ================ =========== ============
Application-steam-x64.exe 14684 Console 1 298.588 K
**1 Inside of Current task FILE!!**
These 1s are from printing result_1.

Using sys.exit in for loops

I am writing a small python script that iterates through a large json output and grabs the information I need and puts it into small dictionaries. It then iterates through the dictionaries to look for an key called restartcount. If the count is more than more than 3 but less than 5 it prints warning. If greater than 5 it prints critical. However this script is set to be a nagios plugin which requires exit codes to be placed with warning sys.exit(1), and sys.exit(2) for critical. If you look at my script I use my function to grab the info I need into a small dictionary, then run a for loop. If I place a sys.exit after inside any if statement I iterate only through the first dictionary and the rest are not checked. Any help will be appreciated as to how to incorporate the exit codes without losing skipping or missing any information.
Code:
import urllib2
import json
import argparse
from sys import exit
def get_content(pod):
kube = {}
kube['name'] = pod["metadata"]["name"]
kube['phase'] = pod["status"]["phase"]
kube['restartcount'] = pod["status"]["containerStatuses"][0]["restartCount"]
return kube
if __name__ == '__main__':
parser = argparse.ArgumentParser( description='Monitor Kubernetes Pods' )
parser.add_argument('-w', '--warning', type=int, help='levels we should look into',default=3)
parser.add_argument('-c', '--critical', type=int, help='its gonna explode',default=5)
parser.add_argument('-p', '--port', type=int, help='port to access api server',default=8080)
args = parser.parse_args()
try:
api_call = "http://localhost:{}/api/v1/namespaces/default/pods/".format(args.port)
req = urllib2.urlopen(api_call).read()
content = json.loads(req)
except urllib2.URLError:
print 'URL Error. Please re-check the API call'
exit(2)
for pods in content.get("items"):
try:
block = get_content(pods)
print block
except KeyError:
print 'Container Failed'
exit(2)
if block["restartcount"] >= args.warning and block["restartcount"] < args.critical:
print "WARNING | {} restart count is {}".format(block["name"], block["restartcount"])
if block["restartcount"] >= args.critical:
print "CRITICAL | {} restart count is {}".format(block["name"], block["restartcount"])
what the block variable looks like:
{'phase': u'Running', 'restartcount': 0, 'name': u'pixels-1.0.9-k1v5u'}
Create a variable called something like exit_status. Initialize it to 0, and set it as needed in your code (e.g. where you are currently calling exit). At the end of program execution, call sys.exit(exit_status) (and no where else).
Rewriting the last section of your code:
exit_status = 0
for pods in content.get("items"):
try:
block = get_content(pods)
print block
except KeyError:
print 'Container Failed'
exit(2)
if block["restartcount"] >= args.warning and block["restartcount"] < args.critical:
print "WARNING | {} restart count is {}".format(block["name"], block["restartcount"])
if exit_status < 1: exit_status = 1
if block["restartcount"] >= args.critical:
print "CRITICAL | {} restart count is {}".format(block["name"], block["restartcount"])
exit_status = 2
sys.exit(exit_status)
The variable approach is correct
Problem is that as you check further you probably set it to 1 when it was already 2 so I would suggest add here a condition not to set it to 1 if it is already 2

updating tkinter window (Python 3.4)

Good Afternoon all,
I've been working on a contact-book program for a school project. I've got all of the underlying code complete. However I've decided to take it one step further and implement a basic interface. I am trying to display all of the contacts using the code snippet below:
elif x==2:
phonebook_data= open(data_path,mode='r',encoding = 'utf8')
if os.stat(data_path)[6]==0:
print("Your contact book is empty.")
else:
for line in phonebook_data:
data= eval(line)
for k,v in sorted(data.items()):
x= (k + ": " + v)
from tkinter import *
root = Tk()
root.title("Contacts")
text = Text(root)
text.insert('1.0', x)
text.pack()
text.update()
root.mainloop()
phonebook_data.close()
The program works, however every contact opens in a new window. I would like to display all of the same information in a single loop. I'm fairly new to tkinter and I apologize if the code is confusing at all. Any help would be greatly appreciated!!
First of all, the top of the snippet could be much more efficient:
phonebook_data= open(data_path,mode='r',encoding = 'utf8') should be changed to
phonebook_data = open(data_path).
Afterwards, just use:
contents = phonebook_data.read()
if contents == "": # Can be shortened to `if not contents:`
print("Your contact book is empty.")
And by the way, it's good practice to close the file as soon as you're done using it.
phonebook_data = open(data_path)
contents = phonebook_data.read()
phonebook_data.close()
if contents == "":
print("Your contact book is empty.")
Now for your graphics issue. Firstly, you should consider whether or not you really need a graphical interface for this application. If so:
# Assuming that the contact book is formatted `Name` `Number` (split by a space)
name_number = []
for line in contents.split("\n"): # Get each line
name, number = line.split()
name_number.append(name + ": " + number) # Append a string of `Name`: `Number` to the list
name_number.sort() # Sort by name
root = Tk()
root.title("Contact Book")
text = Text(root)
text.pack(fill=BOTH)
text.insert("\n".join(name_number))
root.mainloop()
Considering how much I have shown you, it would probably be considered cheating for you to use it. Do some more research into the code though, it didn't seem like the algorithm would work in the first place.

Categories