How to use the navigation-policy-decision-requested signal in Python Webkit - python

How can I use the navigation-policy-decision-requested (or equivalent) in association with webkit_web_policy_decision_ignore()?
The following is a small outtake form my code (the rest is just a wrapper and settings etc):
def check(view, frame, req, nav, policy):
webkit_web_policy_decision_ignore(TRUE)
...
view.connect("navigation-policy-decision-requested", check)
When I load a new page this error is returned:
Traceback (most recent call last):
File "browser.py", line 17, in check_exec
webkit_web_policy_decision_ignore(TRUE)
NameError: global name 'webkit_web_policy_decision_ignore' is not defined
What I'm trying to achieve is that if a certain address have been given, actions will be taken to prevent it from loading via Python. Any suggestions are welcome in the comments and any additional information you may need will be provided upon request.
Now I'm new to Python so please be specific in your answer, criticism and suggestions.

If you are using pygtk, try policy.ignore().
The object names are mapped slightly differently in pygtk. In python shell you can try after executing from gi.repository import WebKit
print dir(WebKit)
to find corresponding object and in your case
help(WebKit.WebPolicyDecision)

Related

Python how to print full stack, including magic methods (dunder methods) used?

I am trying to debug a Python built-in class. My debugging has brought me into the realm of magic methods (aka dunder methods).
I am trying to figure out which dunder methods are called, if any. Normally I would do something like this:
import sys
import traceback
# This would be located where the I'm currently debugging
traceback.print_stack(file=sys.stdout)
However, traceback.print_stack does not give me the level of detail of printing what dunder methods area used in its vicinity.
Is there some way I can print out, in a very verbose manner, what is actually happening inside a block of code?
Sample Code
#!/usr/bin/env python3.6
import sys
import traceback
from enum import Enum
class TestEnum(Enum):
"""Test enum."""
A = "A"
def main():
for enum_member in TestEnum:
traceback.print_stack(file=sys.stdout)
print(f"enum member = {enum_member}.")
if __name__ == "__main__":
main()
I would like the above sample code to print out any dunder methods used (ex: __iter__).
Currently it prints out the path to the call to traceback.print_stack:
/path/to/venv/bin/python /path/to/file.py
File "/path/to/file.py", line 56, in <module>
main()
File "/path/to/file.py", line 51, in main
traceback.print_stack(file=sys.stdout)
enum member = TestEnum.A.
P.S. I'm not interested in going to the byte code level given by dis.dis.
I think, with the stacktrace you are looking at the wrong place. When you call print_stack from a place, that is executed only when coming from a dunder method, this method is very well included in the output.
I tried this code to verify:
import sys
import traceback
from enum import Enum
class TestEnum(Enum):
"""Test enum."""
A = "A"
class MyIter:
def __init__(self):
self.i = 0
def __next__(self):
self.i += 1
if self.i <= 1:
traceback.print_stack(file=sys.stdout)
return TestEnum.A
raise StopIteration
def __iter__(self):
return self
def main():
for enum_member in MyIter():
print(f"enum member = {enum_member}.")
if __name__ == "__main__":
main()
The last line of the stack trace is printed as
File "/home/lydia/playground/demo.py", line 21, in __next__
traceback.print_stack(file=sys.stdout)
In your original code, you are getting the stack trace at a time when all dunder methods have already returned. Thus they have been removed from the stack.
So I think, you want to have a look at a call graph instead. I know that IntelliJ / PyCharm can do this nicely at least in the paid editions.
There are other tools that you may want to try. How does pycallgraph look to you?
Update:
Python makes it actually pretty easy to dump a plain list of all the function calls.
Basically all you need to do is
import sys
sys.setprofile(tracefunc)
Write the tracefunc depending on your needs. Find a working example at this SO question: How do I print functions as they are called
Warning: I needed to start the script from an external shell. Starting it by using the play button in my IDE meant that the script would never terminate but write more and more lines. I assume it collides with the internal profiling done by my IDE.
The official documentation of sys.setprofile: https://docs.python.org/3/library/sys.html#sys.setprofile
And a random tutorial about tracing in Python: https://pymotw.com/2/sys/tracing.html
Note however, that by my experience you can get the best insights into the questions "who is calling whom?" or "where does this value even come from?" by using a plain-old debugger.
I also did some research on the subject matter, as information in #LydiaVanDyke's answer fueled better searches.
Printing Entire Call Stack
As #LydiaVanDyke points out, an IDE debugger is a really great way. I use PyCharm, and found that was my favorite solution, because one can:
Follow function calls + exact line numbers in the code
Read code around the calls, better understanding typing
Skip over calls one doesn't care to investigate
Another way is Python's standard library's trace. It offers both command line and embeddable methods for printing the entire call stack.
And yet another one is Python's built-in debugger module, pdb. This (invoked via pdb.set_trace()) really changed the game for me.
Visualization of Profiler Output
gprof2dot is another useful profiler visualization tool.
source code
useful tutorial
Finding Source Code
One of my other problems was not actually seeing the real source code, due to my IDE's stub files (PyCharm).
How to retrieve source code of Python functions details two methods of actually printing source code
With all this tooling, one feels quite empowered!

CEFPython won't initialized when called from an application

I have a very very specific problem.
I am trying to figure out a way to embed an HTML brower in my app, in order to show some generated HTML content with included javascript.
I tried to do it with wx.html2, but the javascript part just seems to not work.
So I decided to give a try to CEFPython by taking example of the provided wxPython.py demo.
At first, it worked great in the UI I designed.
BUT, the problem is that this UI is intended to be called from another application, as a sort of "plug-in UI". And when launching my wxPython UI from this application, it crashes as soon as cef is initialized (through:
sys.excepthook = cef.ExceptHook
settings = {
"debug": True,
"log_severity": cef.LOGSEVERITY_INFO,
"log_file": "debug.log",
}
cef.Initialize(settings=settings)
app = CefApp(False)
app.MainLoop()
del app
cef.Shutdown()
I keep getting this error:
Python exception: AttributeError
'module' object has no attribute 'argv'
Traceback (most recent call last):
File "<string>", line 248, in <module>
File "<string>", line 36, in main
File "cefpython_py27.pyx", line 626, in cefpython_py27.Initialize
(cefpython_py27.cpp:99136)
AttributeError: 'module' object has no attribute 'argv'
So in the end I have 2 questions:
is there a way with wx.html2 to show HTML content embedding javascript
if not, do you have a clue of what would cause the launched UI to crash? I guess it's a threading matter but I'm not even sure.
Please excuse my english mistakes by the way, as I'm not native.
It seems that your Python environment doesn't behave in a standard manner, you don't provide details how is your Python code called.
The error in cefpython is thrown on this line:
if "--debug" in sys.argv:
application_settings["debug"] = True
https://github.com/cztomczak/cefpython/blob/bbf3597ba47f72db66cf304ab8eb3ccfc3a7130c/src/cefpython.pyx#L631
You have to find out why your Python didn't define "sys.argv". You can easily fix this with code like this: sys.argv = [] before calling cef.Initialize, however you may still encounter other issues due to your non-standard Python environment.

Python3 script to get status of deluge

I want to make a python script that every 30 minutes checks the status of a torrent on my RPI (where deluge is up and running) and if completed sends an email. I know how to make a timer, loop and email, but I don't know about deluge. I've read this: https://media.readthedocs.org/pdf/deluge/latest/deluge.pdf.
I know I need to import deluge and start with get_session_state() and get it to string, but it doesn't work.
Here's the error:
Traceback (most recent call last):
File "torrents_status.py", line 3, in <module>
get_session_state()
NameError: name 'get_session_state' is not defined
If you are just doing import deluge, you have to use the full module name for the methods.
deluge.get_session_state()
However, I'm imagining there is some connection object to the session that you should actually be calling that method on. I don't want to read through that 300 page manual, though, to find the correct module you should import.
Alternatively, you could do something like
from deluge import get_session_state
Then call
get_session_state()
Once again, you'll need to use the correct module name instead of deluge.

Make _tkinter.createfilehandler work again (or provide a workaround)

I've got some old Python scripts which used a different version of tkinter than the current systems are equipped with. Back in the old days, a method named _tkinter.createfilehandler() existed and worked. With the current versions this returns with a RuntimeError exception:
Traceback (most recent call last):
File "src/text.py", line 513, in <module>
tkinter.createfilehandler(pipe_r, READABLE, drain_pipe)
RuntimeError: _tkinter.createfilehandler not supported for threaded Tcl
The script I'm trying to get to run is this (shortened version of course):
#!/usr/bin/env python
import os
from Tkinter import *
(pipe_r, pipe_w) = os.pipe()
# ...
def drain_pipe(a, b):
# handle data from pipe_r
# ...
tkinter.createfilehandler(pipe_r, READABLE, drain_pipe)
tk.mainloop()
Is there a simple way to get this running again? I'm sure there is a way to convert the scripts (or maybe write them anew based on a different paradigm), but I'd be happy with a hack to not have to change very much (maybe there's a switch to enable this again somehow) because I've got several such scripts and would prefer not to have to patch a lot.
If tk is a Tk() object, then use tk.createfilehandler instead.

Plone 3.1.2 - TypeError in ATDocument.getText() method

My task is to unload content from a Plone 3.1.2 website and load information about the content to an SQL database + file system
I've recreated the website, got access to ZODB and recreated object and folder structure. I am also able to read properties of folders, files and documents. I can't get the .getText() method of ATDocument to work. The Traceback looks like this:
Traceback (most recent call last):
File "C:\Users\jan\Eclipse_workspace\Plone\start.py", line 133, in ?
main()
File "C:\Users\jan\Eclipse_workspace\Plone\start.py", line 118, in main
print dokument.getText()
File "e:\Program Files\Plone 3\Data\Products\Archetypes\ClassGen.py", line 54, in generatedAccessor
File "e:\Program Files\Plone 3\Data\Products\Archetypes\BaseObject.py", line 828, in Schema
TypeError: ('Could not adapt', <ATDocument at /*object_path*>, <InterfaceClass Products.Archetypes.interfaces._schema.ISchema>)
I suspect that there is a problem with connecting the object to interface ISchema, but I've never worked with Plone before and don't know it's object model.
Any suggestions what might be wrong or missing, how can I fix it and/or what to do next? I suspect that I have to connect ISchema interface class with this object somehow, but have no idea where to start. Any suggestions?
I'll be greatful for any help since I'm stuck for 2 days now and not moving forward.
I know nothing about ZCML format or how to edit it.
Because after >>> print dokument.getText() in debug mode the script jumps to makeMethod() method in Generator class I assume that the script doesn't execute .getText() but tries to create this method instead.
Since inspect.getmembers(dokument) returns a getText() method I'm really confused.
Do you know in which ZCML file might be related to ATDocument class? Or where can I look for any information on this subject?
My start.py file doesn't do much else than the following imports:
from ZODB.FileStorage import FileStorage
from ZODB.DB import DB
from OFS.Application import Application
from BTrees import OOBTree
from Products.CMFPlone.Portal import PloneSite
then it gets access to dokument object and tries to execute .getText()
Edit 213-03-26 15:27 (GMT):
About the .zcml files
The site I've received was 3 folders: Products (extracted to \Plone 3\Data), lib and package-includes.
Inside the lib there is python folder containing 3 subfolders: 'common', 'abc' and 'def' (names changed not to release client's information). Each of these subfolders contains a configure.zcml file, one of these also includes override.zcml file.
In the folder package-includes there are 4 files, each of them 1 line long. They contain the following lines:
<include package="abc" file="configure.zcml" />
<include package="def" file="overrides.zcml" />
<include package="common" file="configure.zcml" />
<include package="def" file="configure.zcml" />
These zcml files are not copied at the moment. Where can I copy these to have these imported?
You are missing component registrations, usually registered when loading the ZCML files in a site.
You want to end up with the possibility to run bin/instance run yourscript.py instead, which leaves all the tedious site and ZCML loading to Zope.
Once you have that running reliably, you can then access the site in a script that sets up the local component manager and a security manager:
from zope.app.component.hooks import setSite
from Testing.makerequest import makerequest
from AccessControl.SecurityManagement import newSecurityManager
site_id = 'Plone' # adjust to match your Plone site object id.
admin_user = 'admin' # usually 'admin', probably won't need adjusting
app = makerequest(app)
site = app[site_id]
setSite(site)
user = app.acl_users.getUser(admin_user).__of__(site.acl_users)
newSecurityManager(None, user)
# `site` is your Plone site, now correctly set up
Save this script somewhere, and run it with:
bin/instance run path/to/yourscript.py
The way you are starting your task is not the good one.
You are trying to use the API without the framework setup. It's possible but you have to know the framework very well (load the persistent sitemanager, ...)
You should add a 'browser view' and call it to export your content.
You can do that by:
create your own addon and install it
modify an installed addon (hey it's temporary work after all)
You will find documentation about browserview and plone at http://developer.plone.org
Sorry but if you need to develop for Plone you will need to read a bit about all this.

Categories