I'm using Jython and trying to get the user to input a password. However, I would like it to show an asterisk rather than the characters that the user is inputting. I managed to do something similar using getpass, but it required you to type into the cmd line, and it would just not show anything rather than an asterisk.
I'm looking to have the user type into a dialog box; the "input()" command brings up a box that would be perfect. For example, this:
import sys
password = input("Please enter your password: ")
if password == None: #if the user hits cancel
sys.exit(0)
However, it does not mask the text. I am able to do this using the java aspect of jython like so:
import javax.swing.JOptionPane as JOP
import javax.swing.JPasswordField as JPF
import sys
pwdF = JPF()
choice = JOP.showConfirmDialog(None, pwdF,
"Please enter your password:",
JOP.OK_CANCEL_OPTION)
if choice == JOP.CANCEL_OPTION:
sys.exit(0)
password = pwdF.getText()
A problem I have with this is that I can't get the cursor to default to the text field (instead it starts on the ok button). Primarily, though, I'd like a more pythonic way of doing this.
I messed around quite a bit with java.swing, using layout and add components; however, I didn't understand it enough to tweak it in a way that would work.
Does anyone know a method of creating an input box with masked text different from the java version I posted?
Thanks.
You can use javax.swing.JPasswordField class.
An example is this :
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
public class PwdForm extends JFrame {
public JFrame frame;
public PwdForm() {
//Create main Panel
JPanel mainPanel = new JPanel();
//Password field
JLabel lblPwd = new JLabel("Password :");
mainPanel.add(lblPwd);
final JPasswordField txtPwd = new JPasswordField(20);
lblPwd.setLabelFor(txtPwd);
mainPanel.add(txtPwd);
//Confirm Button
final JButton btnOk = new JButton("Confirm");
mainPanel.add(btnOk);
//Create and set up the window.
frame = new JFrame("Password Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
mainPanel.setOpaque(true); //content panes must be opaque
frame.setContentPane(mainPanel);
//Display the window.
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
}
public static void main(String[] args) {
PwdForm lf = new PwdForm();
}
}
Related
I need to write a test using cucumber for a course.
Scenario:
Login,
Select first item link,
Add item to the shopping cart,
Proceed shopping cart page,
Check the item on that list is correct,
Proceed to checkout,
Complete and Logout.
The point I don't understand is, do I need to open a feature file for each step and do I need to close and reopen the browser for each step? How should I do this? What kind of path should I follow?
(Note that I am a beginner and my English skills are limited, so I need a simple explanation.)
Yes, you should make a new file for each feature. For example, login.gherkin, upload.gherkin, logout.gherkin.
PS. Sorry, I didn't realize you said Python, but it's the same idea.
Each file should have a layout like this:
# Created by Mick Jagger at 1/13/2021
#login
Feature: Login
Scenario: Login to Website Homepage
When Launch website
Then Enter username and password
And Log in
Then make the corresponding step file like this:
package glue;
import cucumber.api.java.en.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import java.util.List;
public class LoginSteps extends Driver {
public String username = "username";
public String password = "password";
#When("Launch Website")
public void launch_website() throws Throwable {
driver.get("https://www.website.com/");
Thread.sleep(2000);
}
#Then("^Enter username and password$")
public void enter_credentials() throws Throwable {
driver.findElement(By.xpath("//input[#aria-label='Phone number, username, or email']")).sendKeys(username);
driver.findElement(By.xpath("//input[#aria-label='Password']")).sendKeys(password);
}
#And("^Log in$")
public void log_in() throws Throwable {
Thread.sleep(1000);
List<WebElement> buttons = driver.findElements(By.tagName("button"));
buttons.get(1).click();
Thread.sleep(2000);
driver.findElement(By.tagName("button")).click();
Thread.sleep(1000);
buttons = driver.findElements(By.xpath("//button[#tabindex='0']"));
buttons.get(1).click();
}
}
If you're new to browser automation, I recommend learning the "Page Object Model Methodology". Also, I stopped using this annoying framework, it's supposed to make things easier but to me it just adds extra work.
I have to check with a Python box if a word I've told to Pepper (saved externally from a dialog box) is inside a list (created as string,and saved into ALMemory from SSH in Matlab), and do something if yes or not.
How can I do this?
def onInput_onStart(self):
#self.onStopped() #activate the output of the box
picklist = ALProxy("ALMemory")
list=picklist.getData("myFood")
def food(self):
if food in list:
tts=ALProxy("ALDialog")
tts.say("Available")
I personally would just manage it on the web using js, when it comes to this kind of stuff boxes give more trouble than it's worth. Raise an event with the string you want and check if the word is inside the list. After that you can either use the tts (as you seem to be trying to do) or raise and event (sending the true/false as a parameter) and use it to trigger whatever you want.
Javascript:
session = null
QiSession(connected, disconnected, location.host);
tts = null;
function connected(s) {
console.log("Session connected");
session = s;
startSubscribe();
session.service("ALTextToSpeech").then(function (t) {
tts = t;
});
}
function disconnected(error) {
console.log("Session disconnected");
}
function startSubscribe() {
session.service("ALMemory").then(function (memory) {
memory.subscriber("toTablet").then(function (subscriber) {
subscriber.signal.connect(functionThatChecks)
});
});
}
function functionThatChecks(word)
{
tts.stopAll();
/*Check if exists*/
tts.say("It exists"); //Or raise an event
}
Dialog
u: (word) $eventName="word"
Choregraphe
You need to use self.list before other functions can access it.
You also need to pass users_food to the function when you call food().
Assuming that list is a list of strings, and users_food is a string.
def onInput_onStart(self):
#self.onStopped() #activate the output of the box
picklist = ALProxy("ALMemory")
self.list=picklist.getData("myFood")
def food(self, users_food):
if users_food in self.list:
tts=ALProxy("ALDialog")
tts.say("Available")
I am trying to enable selecting one single space for use in Revit MEP 2019 by using the GUI and store the selection for further use in scripts. The code is written in pyRevit. The script runs both from the shell and from the addin button, but when entering the selection mode (PickObject method), I am not allowed to select anything at all. I don't get any errors, it's just that nothing is selectable when entering the selection tool in the GUI.
I have commented in the code what I have tried that didn't work.
from Autodesk.Revit import DB,UI
from Autodesk.Revit.DB import BuiltInCategory
from Autodesk.Revit.UI.Selection import ISelectionFilter,ObjectType
# Definitions:
# Define a space selection filter so that only spaces are selectable
class SpaceSelectionFilter(ISelectionFilter):
def AllowElement(element):
#if element.Category.Name == "Spaces":
#if element.ToString() == "Autodesk.Revit.DB.Mechanical.Space":
if element.Category.Id.IntegerValue== int(BuiltInCategory.OST_MEPSpaces):
return True
return False
def AllowReference(reference, point):
return False
# Function that enables using PickObject from the PythonRevitShell
def shell_pickobject():
__window__.Hide()
elementReference = uidoc.Selection.PickObject(UI.Selection.ObjectType.Element,spaceFilter,"Select a space(room)")
__window__.Show()
__window__.TopMost = True
return elementReference
# Procedure:
# Create a selection filter
spaceFilter = SpaceSelectionFilter()
# User picks a space
ref = shell_pickobject()
# The following line works also outside of the shell_pickobject() function when used from the GUI addin-button, but spaces are still not selectable.
# elementReference = uidoc.Selection.PickObject(UI.Selection.ObjectType.Element,spaceFilter,"Select a space(room)")
I don't understand where the problem is, my best guess is inside the filter definition. The help string "Select a space(room)" displays correctly in the bottom left corner, and everything but the viewport turns grey like it should when I am supposed to select something in the view. The mouse turns into some kind of "forbidden" symbol.
I would very much appreciate some help with this. Thank you in advance to anyone who might wish to help!
You can find examples in pyRevitMEPÂ source code. I also did an article explaining how to use ISelectionFilter : [Revit] ISelectionFilter example using python. Here is one example (running with revitpythonshell) :
from Autodesk.Revit.UI.Selection import ISelectionFilter
class CustomISelectionFilter(ISelectionFilter):
def __init__(self, category_name):
self.category_name = category_name
def AllowElement(self, e):
if e.Category.Name == self.category_name:
return True
else:
return False
def AllowReference(self, ref, point):
return true
try:
ductsel = uidoc.Selection.PickObject(ObjectType.Element,
CustomISelectionFilter("Ducts"),
"Select a Duct")
except Exceptions.OperationCanceledException:
TaskDialog.Show("Operation canceled","Canceled by the user")
__window__.Close()
You can find another example running under pyRevit explained here :Â [pyRevitMEP] ConnectTo : connect MEP elements
I'm building a web app right now that has a couple of text-fields that I would ideally like to be able to copy (individually) using a "copy" button next to each field. Right now I'm attempting to write a Pyperclip function in my main file, and then passing that as an onclick value for a button, but as soon as the page loads, the Pyperclip function executes and my clipboard is updated without pressing anything. So for example:
#app.route('/converted.html', methods = ['GET', 'POST'])
def converted():
pyperclip_Test = pyperclip.copy("apple")
return render_template('converted.html',
pyperclip_Test = pyperclip_Test)
Then in my template file:
Test
<div>Data that I want to copy</div>
I know the pyperclip function isn't copying that div - I retracted the original data that I can pass - but the problem still remains that the script executes without me pressing the button.
Any idea on how to get this working?
you cannot use pyperclip in a webpage ... you are confusing client side and serverside ... you are copying the text on the serverside clipboard, which does nothing for the client(or anyone else)
try something like the following (javascript)
<script>
function clip_text(a_string){
var input = document.createElement('input')
input.id="__copyText__";
input.value = a_string; // OOPS! document.getElementById(divId).innerText;
document.body.appendChild(input);
input.select();
document.execCommand("copy");
var txt = input.value
input.remove()
console.log("OK COPIED: '"+txt+"'")
}
function clip_div(divId){
return clip_text(document.getElementById(divId).innerText)
}
</script>
and then call it like this
Test
<div id="copyme">Data that I want to copy</div>
I need some hints to find a simple solution for inserting a popup window inside a python console app.
This app runs normally unattended, because it's done to be launched from crontab.
It uses everywhere logging to display messages and save them to logfiles.
However, in some cases, the app needs user intervention to choose some options when it is not able to find a suitable one.
That's why I inserted a --interactive option in argparse, and when the app needs user intervention, a popup window in console should appear, allowing the user to choose between some items in a list.
Here's an extract of the output to give you an example :
INFO : Try to fuzzy-match 'Orange Itbn'
INFO : Fuzzy-matched alternative entries : ['Orange Is The New Black']
INFO : Fuzzy matched 'Orange Itbn' as seriesname 'Orange Is The New Black'
INFO : MOVE /Users/spadazz/testing/orange itbn.s03e10.hdtv.720p.mkv TO:
/Volumes/NAS/TV Shows/Orange Is The New Black/S03/Orange Is The New Black.S03E10.hdtv.720p.mkv
INFO : Try to fuzzy-match 'Sur'
INFO : Fuzzy-matched alternative entries : ['Survivors 2008', 'Survivors']
WARNING :
Series 'Sur' not uniquely matched in titles
Choose between these titles :
['Survivors 2008', 'Survivors']
WARNING :
******************************************
**** INSERT HERE THE CALL TO THE POPUP ***
******************************************
Now, I've read some documentation about tkinter, curses and npyscreen but I wasn't able to come up with something simple for this purpose.
I don't wanna mess with the app structure or put the log messages in a main window..
I just wanna a popup that allows me to choose between some options, even with a simple keypress like '1' and '2' etc...
This should be a python solution too, possibly without calling external commands from os.
Any ideas ??
Thanks
With a little help from Nicholas Cole, who wrote npyscreen, I was able to fix this :
import npyscreen as np
class myPop(np.NPSApp):
def setopt(self, title, oList, multi):
self.title = title
self.options = oList
self.multi = multi
self.height = len(self.options)+1
def main(self):
F = np.Popup(name="Choose an option")
if self.multi:
opt = F.add(np.TitleMultiSelect, name=self.title, max_height=self.height, values=self.options, scroll_exit=True)
else:
opt = F.add(np.TitleSelectOne, name=self.title, max_height=self.height, values=self.options, scroll_exit=True)
F.edit()
self._values = opt.get_selected_objects()
self.result = ( self._values if self.multi and len(self._values) > 1 else self._values[0] )
def ChooseOption(title, oList, multi=False):
pop = myPop()
pop.setopt(title, oList, multi)
pop.run()
return pop.result
# Show a popup with radiobuttons to select 1 item from a list
print ChooseOption('choose a single element', ['a','b','c','d'])
# Show a popup with radiobuttons to multi-select items from a list
print ChooseOption('choose multi-elements', ['a','b','c','d'], True)
Hope this helps.
Enrico
Since npyscreen was written to make that kind of thing really simple, I'd use npyscreen. :)
The example code here is almost exactly what you are asking for.