Access DOMDocument in Python3 - python-3.x

So I'm creating a small program using Oython / GTK+, at it's core is a WebView which displays some HTML-page. I now want to allow the user to manipulate the view by highlighting text, underline text etc. Later I want my program to store this markup in a different file, so it can dynamically be loaded at a later time.
I could simply set the WebView as editable, but then I have to save a changed HTML-document; I rather want to leave the original document untouched and save the user-markup seperately.
My idea was to use the DOM, esp. the DOMDOMSelection and DOMRange functions. The WebKit3.0 API (here) states that
WebKitViewer.get_dom_document()
should return a WebKit.DOMDocument. However, as running the attached MWE (below) shows, this call returns a WebKit.DOMHTMLDocument.
Using this object I don't find a way to access the DOMDocument or DOMDOMSelection I would need to proceed further.
My question:
Q: Is it a known bug or am I using the wrong calls?
EDIT1:
While I am not sure if the return value mentioned above is correct, I found a way to circumwent my problem:
# The still strange return document
DOMHTMLdoc = editor.get_dom_document()
# The view that contains the doc
def_view = DOMHTMLdoc.get_default_view()
# On this view one can finally create a selection
sel = def_view.get_selection()
END_EDIT1
If there is another (easier) way to achive this I'm open for suggestions ;)
Thanks in advance.
Setup:
Linux Antergos 4.9.11-1-ARCH x86_64
Geany
Python3.6.0
gir1.0
MWE
import gi
import os
gi.require_version('Gtk', '3.0')
gi.require_version('WebKit', '3.0')
from gi.repository import Gtk, WebKit
w = Gtk.Window()
w.set_title("Example Editor")
w.set_default_size(800,400)
w.connect("destroy", Gtk.main_quit)
message = "<!DOCTYPE html><html><head><meta charset=\"utf-8\"><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><title>ERSTE SCHRITTE MIT BRACKETS</title><meta name=\"description\" content=\"Ein interaktiver Wegweiser für die ersten Schritte mit Brackets.\"><link rel=\"stylesheet\" href=\"main.css\"></head><body><h1>ERSTE SCHRITTE MIT BRACKETS</h1><h2>Dies ist Ihre Anleitung!</h2><p> Willkommen zu Brackets, einem modernen, quelloffenen Code-Editor, der Webdesign versteht. Es ist ein einfacher, aber dennoch leistungsfähiger Editor, der Ihnen immer die richtigen Tools einblendet, sodass Sie die genau richtige Menge an Hilfestellung haben, wann immer Sie diese brauchen.</p></body></html>"
editor = WebKit.WebView()
status = editor.get_load_status()
DOMHTMLdoc = editor.get_dom_document()
def load_up(self):
editor.load_string(message,"text/html","utf-8","file://")
def show_status(self):
# Give the WebView some time to load everything
status = editor.get_load_status()
if status == 2:
# Here I would expect a DOMDocument to be returned
# but instead I get DOMHTMLDocument
DOMHTMLdoc = editor.get_dom_document()
el = DOMHTMLdoc.get_active_element()
coll = el.get_children()
length = coll.get_length()
print("DOMHTMLdoc: ")
print(DOMHTMLdoc)
# Here I can loop over the elements, but always DOMHTMLxx
print("DOMHTMLElement: ")
print(el)
for i in range(0, length):
print(coll.item(i))
hb = Gtk.HBox()
vb = Gtk.VBox()
b = Gtk.Button("Load")
b.connect("clicked", load_up)
b2 = Gtk.Button("DOM status")
b2.connect("clicked", show_status)
swindow = Gtk.ScrolledWindow()
swindow.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
swindow.add(editor)
hb.add(b)
hb.add(b2)
vb.pack_start(hb, False, False, 0)
vb.add(swindow)
w.add(vb)
w.show_all()
Gtk.main()

Related

ML Studio language studio failing to detect the source language

I am running a program in python to detect a language and translate that to English using azure machine learning studio. The code block mentioned below throwing error when trying to detect the language.
Error 0002: Failed to parse parameter.
def sample_detect_language():
print(
"This sample statement will be translated to english from any other foreign language"
)
from azure.core.credentials import AzureKeyCredential
from azure.ai.textanalytics import TextAnalyticsClient
endpoint = os.environ["AZURE_LANGUAGE_ENDPOINT"]
key = os.environ["AZURE_LANGUAGE_KEY"]
text_analytics_client = TextAnalyticsClient(endpoint=endpoint)
documents = [
"""
The feedback was awesome
""",
"""
la recensione è stata fantastica
"""
]
result = text_analytics_client.detect_language(documents)
reviewed_docs = [doc for doc in result if not doc.is_error]
print("Check the languages we got review")
for idx, doc in enumerate(reviewed_docs):
print("Number#{} is in '{}', which has ISO639-1 name '{}'\n".format(
idx, doc.primary_language.name, doc.primary_language.iso6391_name
))
if doc.is_error:
print(doc.id, doc.error)
print(
"Storing reviews and mapping to their respective ISO639-1 name "
)
review_to_language = {}
for idx, doc in enumerate(reviewed_docs):
review_to_language[documents[idx]] = doc.primary_language.iso6391_name
if __name__ == '__main__':
sample_detect_language()
Any help to solve the issue is appreciated.
The issue was raised because of missing the called parameters in the function. While doing language detection in machine learning studio, we need to assign end point and key credentials. In the code mentioned above, endpoint details were mentioned, but missed AzureKeyCredential.
endpoint = os.environ["AZURE_LANGUAGE_ENDPOINT"]
key = os.environ["AZURE_LANGUAGE_KEY"]
text_analytics_client = TextAnalyticsClient(endpoint=endpoint)
replace the above line with the code block mentioned below
text_analytics_client = TextAnalyticsClient(endpoint=endpoint, credential= AzureKeyCredential(key))

How to bring python message box in front?

I am trying to get windows message box pop in front but every time the message box is called it just pops up in the background on another monitor.
import ctypes
from time import sleep
sleep(5) # for switching to another window
MB_SETFOREGROUND = 0x10000
ctypes.windll.user32.MessageBoxW(None, "This should be in top", "Very important messsage", MB_SETFOREGROUND)
Using MB_SYSTEMMODAL worked to bring the window to the front.
import ctypes
from time import sleep
sleep(5) # for switching to another window
MB_SYSTEMMODAL = 0x00001000
ctypes.windll.user32.MessageBoxW(None, "This should be in top", "Very important message", MB_SYSTEMMODAL)
I always recommend using .argtypes and .restype to ensure parameters are marshaled correctly between Python and C and it allows ctypes to better error check parameters:
import ctypes as ct
import ctypes.wintypes as w
import time
dll = ct.WinDLL('user32', use_last_error=True)
dll.MessageBoxW.argtypes = w.HWND, w.LPCWSTR, w.LPCWSTR, w.UINT
dll.MessageBoxW.restype = ct.c_int
MB_SYSTEMMODAL = 0x00001000
IDOK = 1
print('Waiting...')
time.sleep(5)
result = dll.MessageBoxW(None, "This should be in top", "Very important message", MB_SYSTEMMODAL)
print(result == IDOK)

How to fix unidentified character problem while passing data from TKinter to Photoshop via Python script?

I made a GUI Application which looks like this:
The ones marked red are Tkinter Text widgets and the ones marked yellow are Tkinter Entry widgets
After taking user input, the data is to be added to a PSD file and then rendered as an image. But Lets say, after taking the following data as input:
It renders the following Photoshop file:
How do I fix this issue that it does not recognize "\n" properly and hence the rendered document is rendered useless.
Here is the code which deals with converting of the accepted user data into strings and then adding it to Photoshop template and then rendering it:
def DataAdder2CSV():
global edate, eSNO, eage, egender, ename, ePID, econtact, ecomp, eallergy, ehistory, eR
e=edate.get()
a=eSNO.get()
d=eage.get()
f=egender.get()
b=ename.get()
c=ePID.get()
g=econtact.get()
h=ecomp.get(1.0,END)
i=eallergy.get(1.0,END)
j=ehistory.get(1.0,END)
k=eR.get(1.0,END)
data=[a,b,c,d,e,f,g,h,i,j,k]
file=open("Patient_Data.csv","a", newline="")
writer=csv.writer(file, delimiter=",")
writer.writerow(data)
file.close()
messagebox.showinfo("Prescription Generator", "Data has been saved to the database successfully!")
import win32com.client, os
objShell = win32com.client.Dispatch("WScript.Shell")
UserDocs = objShell.SpecialFolders("MyDocuments")
from tkinter import filedialog
ExpDir=filedialog.askdirectory(initialdir=UserDocs, title="Choose Destination Folder")
psApp = win32com.client.Dispatch("Photoshop.Application")
psApp.Open("D:\Coding\Python Scripts\Dr Nikhil Prescription App\Prescription Generator\Presc_Template.psd")
doc = psApp.Application.ActiveDocument
lf1 = doc.ArtLayers["name"]
tol1 = lf1.TextItem
tol1.contents = b
lf2 = doc.ArtLayers["age"]
tol2 = lf2.TextItem
tol2.contents = d
lf3 = doc.ArtLayers["gender"]
tol3 = lf3.TextItem
tol3.contents = f
lf4 = doc.ArtLayers["pid"]
tol4 = lf4.TextItem
tol4.contents = c
lf4 = doc.ArtLayers["date"]
tol4 = lf4.TextItem
tol4.contents = e
lf5 = doc.ArtLayers["contact"]
tol5 = lf5.TextItem
tol5.contents = g
lf6 = doc.ArtLayers["complaint"]
tol6 = lf6.TextItem
varH=" "+h.rstrip("\n")
tol6.contents =varH
lf7 = doc.ArtLayers["allergy"]
tol7 = lf7.TextItem
tol7.contents = i.rstrip("\n")
lf8 = doc.ArtLayers["history"]
tol8 = lf8.TextItem
varJ=" "+j.rstrip("\n")
tol8.contents =varJ
lf9 = doc.ArtLayers["R"]
tol9 = lf9.TextItem
tol9.contents = k.rstrip("\n")
options = win32com.client.Dispatch('Photoshop.ExportOptionsSaveForWeb')
options.Format = 13
options.PNG8 = False
pngfile =ExpDir+f"/{c}-{b}_({e}).png"
doc.Export(ExportIn=pngfile, ExportAs=2, Options=options)
messagebox.showinfo("Prescription Generator", "Prescription has been saved in the desired location successfully!")
There are 3 ways of expressing new line characters:
MacOS uses \r
Linux uses \n
Windows uses \r\n
Python and tkinter use \n but it looks like psApp.Application uses \r instead. That is why the document isn't rendered properly. For more info read the answers to this question.

Python error "expected LP_SDL_Window" when trying "SDL_GetWindowID"

I'm trying to get the Window ID of the SDL window, to give to VLC so it can play the video in the window.
Being new to Python, I'm vaguely aware this has to do with variable type conversions to play nice with SDL, and using the correct python binding...
The line with the error is "win_id = SDL_GetWindowID(window)"
Here is my code;
import sys
import sdl2.ext
import vlc
import ctypes
from sdl2 import *
RESOURCES = sdl2.ext.Resources(__file__, "resources")
sdl2.ext.init()
window = sdl2.ext.Window("Hello World!", size=(640, 480))
window.show()
factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)
sprite = factory.from_image(RESOURCES.get_path("hello.bmp"))
spriterenderer = factory.create_sprite_render_system(window)
spriterenderer.render(sprite)
vlcInstance = vlc.Instance("--no-xlib")
player = vlcInstance.media_player_new()
win_id = SDL_GetWindowID(window)
player.set_xwindow(win_id)
player.set_mrl("agro.mp4")
player.play()
processor = sdl2.ext.TestEventProcessor()
processor.run(window)
sdl2.ext.quit()
What you get with SDL_GetWindowID is SDL's internal window ID that it itself refers to in e.g. events. What you need is X11 window ID, which you can get through SDL_GetWindowWMInfo. That however requires some trickery with SDL versioning, e.g. (I'm not sure it is safe to call that in python if SDL version changes but pysdl2 is not updated):
wminfo = SDL_SysWMinfo();
SDL_GetVersion(wminfo.version);
if(SDL_GetWindowWMInfo(window.window, wminfo) == 0):
print("can't get SDL WM info");
sys.exit(1);
win_id = wminfo.info.x11.window;
Then use that win_id to feed to vlc.

Error using checkmouse

I'm trying to use checkmouse in order to undraw something from my window. When someone clicks the button it should undraw the text and write something else. I'm using checkMouse and getX() and getY() to do this but i keep receiving this error that states:
File "C:\Users\User\Documents\python\project2.py", line 71, in panel
if (clicknew.getX()>90 and clicknew.getX()<210) and (clicknew.getY()>35 and clicknew.getY() < 0):
AttributeError: 'NoneType' object has no attribute 'getX'
this code that i have done so far is as follows:
from graphics import *
#creating the game panel window
def panel():
#grey window, with coordinates flipped, with banners etc
win = GraphWin("Start Panel", 300,200)
win.setCoords(0,0,300,200)
win.setBackground("light grey")
#drawing the BoilerMazer banner with text
boilermazer = Rectangle(Point(0,200),Point(300,160))
boilermazer.setFill("white")
boilermazer.draw(win)
#text inside
banner1 = Text(Point(150,180),"BoilerMazer")
banner1.setStyle("bold")
banner1.setSize(20)
banner1.draw(win)
#initial game panel is going to have two buttons and a top scores object
#top score "screen"
toprec = Rectangle(Point(60,140),Point(240,50))
toprec.setFill("white")
toprec.draw(win)
#text inside toprec
topscores = Text(Point(150,130),"TOP SCORES")
topscores.setSize(8)
topscores.draw(win)
border = Text(Point(150,120),"======")
border.draw(win)
bigmac = Text(Point(150,110),"Big Mac 21")
bigmac.setSize(8)
bigmac.draw(win)
tt = Text(Point(150,90),"T.T 23")
tt.setSize(8)
tt.draw(win)
cshell = Text(Point(150,75),"C-Shell 25")
cshell.setSize(8)
cshell.draw(win)
macmac = Text(Point(150,55),"MacMac 27")
macmac.setSize(8)
macmac.draw(win)
#new player button that will eventually be clicked
new1 = Point(90,35)
new2 = Point(210,0)
newrec = Rectangle(new1,new2)
newrec.setFill("chartreuse2")
newrec.draw(win)
#new player button text
newplayer = Text(Point(150,18),"NEW PLAYER")
newplayer.draw(win)
#reset button
resetrec = Rectangle(Point(240,35),Point(300,0))
resetrec.setFill("red")
resetrec.draw(win)
#resettext
reset = Text(Point(270,18),"RESET")
reset.draw(win)
#secondary panel window is the game panel after they click new player
#set up points that we check between for the new player button first
#setting up the checkmouse
clicknew = win.checkMouse()
if (clicknew.getX()>90 and clicknew.getX()<210) and (clicknew.getY()>35 and clicknew.getY() < 0):
newplayer.undraw()
you can find the graphics window here:http://mcsp.wartburg.edu/zelle/python/graphics.py
I don't understand what I'm doing wrong, is there some other method that I'm supposed to be using? Thanks for your help
According to the docs, checkMouse() returns None if no mouse click has been detected priorly. So that seems to be the case.
You could put a loop around the call to checkMouse and keep checking if clicknew is not None and only in that case go on in your program. But maybe there's a better way...
UPDATE:
Example:
while True:
clicknew = win.getMouse()
if clicknew:
break
else:
time.sleep(0.1) # avoid busy waiting
# clicknew is set now => use it

Resources