Python/Gtk3 : How to add a Gtk.Entry to a Gtk.MessageDialog? - gtk3

Good morning,
I'm trying to add a Gtk.Entry to a Gtk.MessageDialog. With the following code it seems that I added the Gtk.Entry but it's not visible on the dialog window (Python3/Gtk3):
#!/usr/bin/python3
from gi.repository import Gtk
def get_user_pw(parent, message, default=''):
dialogWindow = Gtk.MessageDialog(parent,
Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
Gtk.MessageType.QUESTION,
Gtk.ButtonsType.OK_CANCEL,
message)
dialogBox = dialogWindow.get_content_area()
userEntry = Gtk.Entry()
userEntry.set_visibility(False)
userEntry.set_invisible_char("*")
userEntry.set_size_request(250,0)
userEntry.set_text("Test")
dialogBox.pack_end(userEntry, False, False, 0)
#dialogWindow.vbox.pack_start(userEntry, False, False, 0)
response = dialogWindow.run()
text = userEntry.get_text()
dialogWindow.destroy()
if response == Gtk.ResponseType.OK:
return text
else:
return None
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="MyWindowTitle")
userPassphrase = get_user_pw(self, "SSH key passphrase")
print("User passphrase: " + userPassphrase)
This code prints :
User passphrase: Test
I'm looking for clues about making the entry visible and editable, any help is welcome.
References:
http://python-gtk-3-tutorial.readthedocs.org/en/latest/dialogs.html
http://developer.gnome.org/gtk3/3.2/GtkDialog.html
Simple, versatile and re-usable entry dialog (sometimes referred to as input dialog) in PyGTK

Ok it works now, I needed to show_all() before run(). It took me some times to figure out this simple thing. Debugged code is :
def get_user_pw(parent, message, title=''):
# Returns user input as a string or None
# If user does not input text it returns None, NOT AN EMPTY STRING.
dialogWindow = Gtk.MessageDialog(parent,
Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
Gtk.MessageType.QUESTION,
Gtk.ButtonsType.OK_CANCEL,
message)
dialogWindow.set_title(title)
dialogBox = dialogWindow.get_content_area()
userEntry = Gtk.Entry()
userEntry.set_visibility(False)
userEntry.set_invisible_char("*")
userEntry.set_size_request(250,0)
dialogBox.pack_end(userEntry, False, False, 0)
dialogWindow.show_all()
response = dialogWindow.run()
text = userEntry.get_text()
dialogWindow.destroy()
if (response == Gtk.ResponseType.OK) and (text != ''):
return text
else:
return None
I use it like this :
class MainWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="MyWindowTitle")
userPassword = get_user_pw(self, "Please enter your password", "Password")

This may be going about it the hard way if this is just to run a sudo command - you could simply call
os.system('pkexec (yourcommand)')

Related

Read message body of an email using Apache Nifi

Is it possible to retrieve the body content of email, email header details and email attachments in Single step using Apache Nifi.
If so Please help me how to achieve this.
It is not possible in a single step unless you write your own processor or script (using ExecuteScript or InvokeScriptedProcessor). However it is possible in a single flow with something like the following:
ConsumePOP3 -> ExtractEmailHeaders -> ExtractEmailAttachments -> ...
At the end of the flow above, you will have one flow file per attachment, each flow file containing the email headers as attributes and the attachment as the content.
You can use the processor "ExecuteScript", not developing custom processor.
import email
import mimetypes
from email.parser import Parser
from org.apache.commons.io import IOUtils
from java.nio.charset import StandardCharsets
from java.io import BufferedReader, InputStreamReader
from org.apache.nifi.processors.script import ExecuteScript
from org.apache.nifi.processor.io import InputStreamCallback
from org.apache.nifi.processor.io import StreamCallback
class PyInputStreamCallback(InputStreamCallback):
_text = None
def __init__(self):
pass
def getText(self) :
return self._text
def process(self, inputStream):
self._text = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
flowFile = session.get()
if flowFile is not None :
reader = PyInputStreamCallback()
session.read(flowFile, reader)
msg = email.message_from_string(reader.getText())
body = ""
if msg.is_multipart():
for part in msg.walk():
ctype = part.get_content_type()
cdispo = str(part.get('Content-Disposition'))
if ctype == 'text/plain' and 'attachment' not in cdispo:
body = part.get_payload(decode=True) # decode
break
else:
body = msg.get_payload(decode=True)
flowFile = session.putAttribute(flowFile, 'msgbody', body.decode('utf-8', 'ignore'))
session.transfer(flowFile, ExecuteScript.REL_SUCCESS)
Screenshot
The gist above posted by #Thomas mostly worked for me.
However, there were cases where the multipart mail was multi-level, i.e. one of the parts was also multipart. To address that, you could use this version of the getTextFromMessage method instead:
private String getTextFromMessage(Part part) throws MessagingException, IOException {
String result = null;
if (part.isMimeType("text/plain")){
// If the part is a plaintext message, just return the content as a String
Object content = part.getContent();
if (content instanceof String) {
result = (String)content;
}
} else if (part.isMimeType("multipart/*")) {
// If the part is a multi-part message, iterate over the sub-parts
MimeMultipart mimeMultipart = (MimeMultipart)part.getContent();
int count = mimeMultipart.getCount();
for (int i = 0; i < count; i ++){
final BodyPart bodyPart = mimeMultipart.getBodyPart(i);
// Inserted from here...
final String text = getTextFromMessage( bodyPart );
if (text != null) {
result = text;
break;
}
}
}
// Just to be safe...
result = (result != null) ? result : "";
return result;
}
Note that it is possible that there is not even a "html/plain" part at all in the email, so you may want to think about how to handle that case as well. For instance, you could loop over the parts again to extract the "text/html" part (if it exists) and deal with that, and so on.

How to set defaut value for a many2one field in Odoo 9.0c?

I have customized a module that include a many2one field. Now, I would like to set the default value for that field with the codition is: [[u'bom_ids', u'!=', False]]. i have tried below code but it did not work probebly
width_id = field.Many2one('sale.order.line.width', default ='_get_width_default')
def _get_width_default(self, cr, uid, context=None):
res = self.pool.get('product.template').search(cr, uid, [(u'bom_ids', u'!=', False)], context=context)
return res and res[0] or False
default = {
'width_id' : _get_width_default,
}
Could you guy please help me to point what is the problem and how to sovle the problem and finnally get my purpose. Thank for watching
import logging
_logger = logging.getLogger(__name__)
def _get_width_default(self, cr, uid, context=None):
#REPLACE DOMAIN WITH SOMETHING RELEVANT
domain = []
res = self.pool.get('sale.order.line.width').search(cr, uid, domain, context=context)
_logger.info("PREPARING DEFAULT VALUE")
_logger.info(res)
return res[0] or False
width_id = fields.many2one('sale.order.line.width')
_defaults = {
'width_id' : _get_width_default,
}
What do you see as far as logging is concerned? Try the above code (v7 style).
Odoo9 Style (NEW API)
import logging
_logger = logging.getLogger(__name__)
def _get_width_default(self):
#REPLACE DOMAIN WITH SOMETHING RELEVANT
domain = []
res = self.env['sale.order.line.width'].search(domain)
_logger.info("PREPARING DEFAULT VALUE")
_logger.info(res)
return res[0].id or False
width_id = fields.many2one('sale.order.line.width',default=_get_width_default)

How do I handle data entry in a scala.js bootstrap modal dialog?

I am using scala.js, plus the bootstrap facade, to collect some data from my user:
def showModal(kopiUser: KopiUser): Unit = {
def modal = Modal().withTitle("modal title").
withBody(
p(s"${kopiUser.displayName}, please enter your data"),
Form(
FormInput.text("fieldlabel")
)
).
withButtons(
Modal.closeButton(),
Modal.button("Submit", Modal.dismiss)
)
modal.show()
}
When the user hits "Submit", I want to get the data that was entered and do something with it.
The dialog is animated, sliding and fading in and out as per bootstrap default, so I can't just register an onClick on the button, right?
How do I do this in a nice way - i.e. preferably some kind of bootstrap/scala.js kind of way, so that I retain my type safety?
I've looked in the bootstrap/scala.js project example, but that just displays an example dialog, it doesn't do anything with the data.
I've intentionally left off the bootstrap tag from this question, I'm looking for how to solve this with scala.js (via the bootstrap facade or not), rather than just using bootstrap itself.
This is modified example of object TestModal from bootstrap/scala.js v1.1.1. There are certainly also other ways to do this but one solution is to move field definitions out of the apply() and out of the form.
This way you can see and use them outside the TestModal2 object.
object TestModal2 {
val modalInputValue = Var("10000000") // Better use string
val radioGroup = FormInput.radioGroup(FormInput.radio("Test1", "modal-title", "First radio"), FormInput.radio("Test2", "modal-title", "Second radio"))
val select = FormInput.simpleSelect("Plain select", "Option 1", "Option 2", "Option 3")
val multipleSelect = FormInput.simpleMultipleSelect("Multiple select", "Option 1", "Option 2", "Option 3")
val inputTextArea = FormInput.textArea("Money text area", rows := 1, modalInputValue.reactiveInput)
val selectedFile = Var("")
val inputFile = FormInput.file("Test file", onchange := Bootstrap.jsInput { input ⇒
val file = input.files.head
selectedFile.update(file.name)
window.alert(s"File selected: ${file.name}")
})
val form = Form(
FormInputGroup(FormInputGroup.label("Money"), FormInputGroup.addon("usd".fontAwesome(FontAwesome.fixedWidth)), FormInputGroup.number(modalInputValue.reactiveInput)),
radioGroup,
select,
multipleSelect,
inputTextArea,
inputFile
)
def apply()(implicit ctx: Ctx.Owner): Modal = {
Modal()
.withTitle(radioGroup.value, " / ", select.selected.map(_.head), " / ", multipleSelect.selected.map(_.mkString(" + ")))
.withBody(p("You won ", modalInputValue, "$"), p(form))
.withButtons(Modal.closeButton(), Modal.button("Take", Modal.dismiss))
}
}
If you put somewhere in the calling code e.g. this
TestModal2.modalInputValue.trigger(
println("modalInputValue = " + TestModal2.modalInputValue.now)
)
TestModal2.select.selected.trigger(
println("select = " + TestModal2.select.selected.now)
)
TestModal2.selectedFile.trigger(
println("selectedFile = " + TestModal2.selectedFile.now)
)
You see the input value changes immediately on the console when they happen on the open dialog.
This is the answer I was given by the maintainer of the scalajs-bootstrap project.
def showModal(kopiUser: KopiUser): Unit = {
val data = Var("")
def modal = Modal().withTitle("modal title").
withBody(
p(s"${kopiUser.displayName}, please enter your data"),
Form(
FormInput.text("fieldlabel", data.reactiveInput)
)
).
withButtons(
Modal.closeButton(),
Modal.button("Submit", Modal.dismiss, onclick := Bootstrap.jsClick { _ ⇒
// Do something with input
window.alert(data.now)
})
)
modal.show()
}
To do what I wanted (including not closing the dialog when data was not entered), I had to additionally hack up the Modal facade class so that I could register onHide, onHidden events to not close the dialog, etc.

How to close the xxxxx.exe terminal window without killing the xxxxx process?

How does this Emacs command (make-comint-in-buffer "Python" nil "python" nil "-i") or (make-comint-in-buffer "git" nil "C:/Program Files (x86)/Git/bin/sh.exe" nil "--login" "-i") manage to get the prompt in an Emacs buffer and get ride of it's, Python's/sh.exe's, interactive terminal without killing the Python process?
I tried to figure out by taking a shallow dive into make-comint-in-buffer's source code but bumped into processp, which is C compiled code, whose source I couldn't find.
The reason I am asking this question is to find an alternative answer to this question without using pythonw (their aint a mayapyw.exe to mayapy.exe for example).
Emacs uses the SHOWWINDOW flag to CreateProcess to control display of the console window associated with a subprocess.
The key code from create_child in w32proc.c is:
if (NILP (Vw32_start_process_show_window) && !is_gui_app)
start.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
else
start.dwFlags = STARTF_USESTDHANDLES;
start.wShowWindow = SW_HIDE;
if (!CreateProcess (exe, cmdline, &sec_attrs, NULL, TRUE, flags, env, dir, &start, &cp->procinfo))
{ ...
}
I can only guess how that Emacs command works, so can't really help you there... But however, I can provide you with a way to hide a window. That is possible by using the CTypes module and call the Windows-API to get the Window/Python-prompts ID/Hwin, and then hide that window.
This forces you to import/or include this piece of code in your script, and then call a function/do a little something in your script. Once your script is run, this should hide the prompt. See "main.py"-part for usage.
Window.py
from ctypes import *
user32 = windll.user32
BOOL = c_bool
INT = c_int
LONG = c_long
LPVOID = c_void_p
LPTSTR = c_wchar_p
HWND = LPVOID
LPARAM = LPVOID
GW_OWNER = 4
GWL_EXSTYLE = -20
WS_EX_TOOLWINDOW = 128
WS_EX_APPWINDOW = 262144
#------------------------------------------------------------------------
def GetWindowLong(hwnd, index):
user32.GetWindowLongW.argtypes = [HWND, INT]
return user32.GetWindowLongW(hwnd, index)
def GetWindow(hWnd, uCmd):
user32.GetParent.argtypes = [HWND, INT]
return user32.GetWindow(hWnd, uCmd)
def GetParent(hwnd):
user32.GetParent.argtypes = [HWND]
return user32.GetParent(hwnd)
def IsWindowVisible(hwnd):
user32.IsWindowVisible.argtypes = [HWND]
return user32.IsWindowVisible(hwnd)
def GetWindowTextLength(hwnd):
user32.GetWindowTextLengthW.argtypes = [HWND]
return user32.GetWindowTextLengthW(hwnd)
def GetWindowText(hwnd):
length = GetWindowTextLength(hwnd)
if not length: return False
buff = create_unicode_buffer(length + 1)
user32.GetWindowTextW.argtypes = [HWND, LPTSTR, INT]
res = user32.GetWindowTextW(hwnd, buff, length + 1)
if res: return buff.value
else: return False
def isRealWindow(hwnd):
""" Check if a given window is a real Windows application frame..
Returns a BOOL """
if not IsWindowVisible(hwnd):
return False
if GetParent(hwnd) != 0:
return False
hasNoOwner = GetWindow(hwnd, GW_OWNER) == 0
lExStyle = GetWindowLong(hwnd, GWL_EXSTYLE)
if (((lExStyle & WS_EX_TOOLWINDOW) == 0 and hasNoOwner)
or ((lExStyle & WS_EX_APPWINDOW != 0) and not hasNoOwner)):
if GetWindowText(hwnd):
return True
return False
class WindowEnumerator(object):
""" Window enumerator class. You can pass it's instances
as callback functions in window enumeration APIs. """
def __init__(self):
self.hwnd = []
def __call__(self, hwnd, lParam):
self.hwnd.append(hwnd)
return True
class __EnumWndProc(WindowEnumerator):
pass
def EnumWindows():
WNDENUMPROC = WINFUNCTYPE(BOOL,HWND,LPARAM)
_EnumWindows = user32.EnumWindows
_EnumWindows.argtypes = [WNDENUMPROC, LPARAM]
_EnumWindows.restype = BOOL
EnumFunc = __EnumWndProc()
lpEnumFunc = WNDENUMPROC(EnumFunc)
if not _EnumWindows(lpEnumFunc, None):
errcode = GetLastError()
if errcode not in (ERROR_NO_MORE_FILES, ERROR_SUCCESS):
raise WinError(errcode)
return EnumFunc.hwnd
def GetWindowByName(title):
window = []
hwnds = EnumWindows()
for hwnd in hwnds:
if not isRealWindow(hwnd):
pass
else:
wndtitle = GetWindowText(hwnd)
if title.lower() in wndtitle.lower():
return (hwnd, wndtitle)
return False
def ShowWindow(hWnd, arg=0):
user32.ShowWindow.argtypes = [HWND, c_int]
return user32.ShowWindow(hWnd, arg)
main.py
import Window
# Pass the full or partial title of the window that should be hidden.
wnd = Window.GetWindowByName('xxxxxxx.exe')
if wnd:
Window.ShowWindow(wnd[0], 0) #Hide it. 0=SW_HIDE, 5 = SW_SHOW.
I hope this does the trick.

how to get autocomplete text box value using lift web

I am using Lift web framework.
I am implementing an auto-complete text box. When I enter some value in the box a drop-down list opens. If I select a value from that list, only then I am able to access value of text box. If I write a value by myself then I get an empty value.
My code :
var friend_name=""
"#bdayReminder" #> AutoComplete("",
getAllName _,
value => takeAction(value),
List("minChars" -> "3"))
private def takeAction(str: String) {
friend_name = str
}
Please suggest a solution
Disclaimer: I'm the author of following library.
I think lift-combobox could achieve what you want, since it has a feature that let user created the value on-the fly. It use select2 jQuery plugin, so you will have a nice look and feel for the drop-down menu.
For example if you need to get the user-created value, it will simply as the following, note that we usually using Option[T] to denote that the value may not be presented, for example, the user may not selected any item in drop-menu at all:
var friend_name: Option[String] = None
val friendsMenu = new ComboBox(
default = None,
allowCreate = true
) {
// This is where you build your combox suggestion
override def onSearching(term: String): List[ComboItem] = {
val names = List(
ComboItem("f1", "Brian"), ComboItem("f2", "Alice"),
ComboItem("f3", "Luke"), ComboItem("f4", "Smith"),
ComboItem("f5", "Brandon")
)
names.filter(_.text.contains(term))
}
override def onItemSelected(selected: Option[ComboItem]): JsCmd = {
friend_name = selected
// The returned JsCmd will be executed on client side.
Alert("You selected:" + selected)
}
// What you want to do if user added an item that
// does not exist when allowCreate = true.
override def onItemAdded(text: String): JsCmd = {
friend_name = Some(text)
}
}
"#bdayReminder" #> friendsMenu.combobox