I have the following table set up using flask-table
class ScreeningTable(Table):
timedate = DatetimeCol('Date & Time', datetime_format='YYYY-MM-d, HH:MM')
tickets = Col('Tickets available')
I want to add a ButtonCol using a screeningID variable, where every button has the same text, but sends the user to a link based on the value of screeningID for each line of the table. How do I do that?
This is the line I came up with:
screeningID = ButtonCol("Buy Tickets", "purchase", url_kwargs=dict(id='screeningID'))
To clarify, the first variable is the title of the header, which will also be the text on the button. The second one is the endpoint, and the third is the keyword argument, what gets pass over as part of the URL.
The same rules apply with LinkCols, as they were written to work identically.
Related
I'm trying to build a script, that can click on the Facebook group category "join" button, when certain conditions are met.
The script is already able to navigate "https://www.facebook.com/search/groups/?q=nature_lover" path using selenium.
Image: https://i.stack.imgur.com/3QJhy.png
After navigating to that path I used this code to handle, each group component data.
all_group_elements = self.driver.find_elements(By.CSS_SELECTOR, "div[role=article]")
for group_element in group_elements:
group_name = str(element.text.split('\n')[0])
group_button = str(element.text.split('\n')[-1])
if group_button=="Join":
group_button_target = f"Join Group {group_name}"
if group_button=="Follow Group":
group_button_target = f"Follow Group {group_name}"
# I used this code to target and click the "join" button.
self.driver.find_element(By.CSS_SELECTOR, f"div[aria-label={group_button_target}]").click()
I'm also using "WebDriverWait" in the script. What is the issue here?
Your issue is with f"div[aria-label={group_button_target}]"
That translates to something like "div[aria-label=Join Group NAME]"
That's a problem, because the value of the attribute contains spaces and you need quotes around the value if there are spaces.
Eg:
Bad: 'TAG[ATTRIBUTE=SOME VALUE]'
Good: 'TAG[ATTRIBUTE="SOME VALUE"]'
Those quotes are important if the value contains spaces. You may want to change that line to:
self.driver.find_element(By.CSS_SELECTOR, f'div[aria-label="{group_button_target}"]').click()
So I have an embed like in the picture, I would like to get the user id from that embed, is there any way to do it?
What have I tried so far:
to_dict With Discord.py, is there a way to read embedded messages? Couldn't get to the value of the field
.fields https://discordpy.readthedocs.io/en/latest/api.html?highlight=#discord.Embed.fields same result as to_dict
.set_field_at https://discordpy.readthedocs.io/en/latest/api.html?highlight=#discord.Embed.set_field_at didn't work, required me to change the value
set_field_at() is a function that will update the contents of a field. You will not be able to retrieve the contents with this method.
You can still use .fields. You can put something similar to the following in the method of your choice.
embed = # Put the Embed in the picture as a discord.Embed object and assign it to this variable
for field in embed.fields: # Dynamically get the user id field.
if field.name.lower() == "user id": # I recommend copying and pasting the field of choice, just in case the characters are not the same visually.
user_id_field = field
break
else: # In case the field isn't found
pass # Put some code here
user_id = int(user_id_field.value) # Get the value of the field
# Either send or print it
References:
discord.Embed.fields - Get a list of the fields from an embed.
discord.Embed.add_field() - denotes the attributes from a field
I have been working with Flask for a little while and developed a database manager application for managing internal data for the department I work in (I am not a "real" developer but have learned by doing/necessity). The application works great as a basic CRUD app. In it I have used Flask forms and tables including the LinkCol column for linking to different functions within the app. In those cases, I am using an 'Edit' or 'Delete' clickable link; meaning every column in the table has an extra cell with that word. Clicking either of those takes the user to the corresponding page where they can take appropriate action on that item.
Currently I am trying to use LinkCol so that data returned from the database can be the clickable link that links to another function rather than every table having an additional column (for example, "Go to Account"). So, when my table populates with an account number, the user can click the actual account number in the table to go to a different page to view additional data about that specific account. I read the docs and looked at the examples on the creators page regarding overwriting things in the classes but haven't been able to figure it out. I have written a few of my own classes, but am not an expert on the matter by any means. I also have been unable to find anything else that might help including on SO which is always my go to resource for figuring things out.
Here is my table definition using a LinkCol that renders incorrectly and puts 'Account #' in each cell instead of the dynamic data I would like. Changing to Col gives correct display but I want it to be clickable:
class AccountsResults(MainTable):
AccNo = LinkCol('Account #','dbhome_bp.route.account_detail', url_kwargs=
dict(AccNo='AccNo',StatusCode='Active',ServiceAddress1=\
'ServiceAddress1'))
TnCount = Col('Total TNs')
ServiceAddress1 = Col('Service Address')
ServiceCity = Col('Service City')
ServiceZip = Col('Service Zip Code')
MasterServiceDate = Col('Master Service Date')
Active = Col('Currently Active')
Here is an example of what I know I can do versus what I would like to do.
Can do ('Go To Account' is clickable in the Go To Account column):
Go To Account
Account #
Service Address
Etc.
Go To Account
12345678
1234 Anywhere
Yup
Go To Account
12345679
5678 Somewhere
Nah
Would like to do (Account numbers are clickable in Account # column ):
Account #
Service Address
Etc.
12345678
1234 Anywhere
Yup
12345679
5678 Somewhere
Nah
Does anyone know how to make the dynamic data returned from a query the clickable link for a LinkCol in Flask Table?
Any help is greatly appreciated.
Assuming an Sqlalchemy model Account with PK column id and a route defined as follows:
accounts = Blueprint('accounts', __name__)
#accounts.route("/accounts/<int:account_id>")
def detail(self, account_id):
_account = Account.get_or_404(account_id)
# show account details
return render('account-details.html', account=_account)
Define your account link column as follows:
account = LinkCol(
name='Account #',
attr='id',
endpoint='accounts.detail',
url_kwargs=dict(account_id='id'),
)
The parameter meanings are as follows:
name # the column header text
attr # the name of the attribute of the account object to render as the text in the <td> cell
endpoint # the endpoint to link to
url_kwargs # the arguments that get passed to the url_for function along with the endpoint
The links would be constructed as if you had done a url_for for each row in the table as follows:
_row_account_detail_url = url_for('accounts.detail', account_id=row_id)
Example Table definition:
class AccountTable(Table):
account = LinkCol(
name='Account #',
attr='id',
endpoint='accounts.detail',
url_kwargs=dict(account_id='id'),
)
service_address = Col(
'Service Address',
attr='service_address'
)
# other columns
I am working on a Python program that needs to add caption texts in MS Word to Figures and Tables (with numbering). After adding the field however, the field does not appear in my Word-document until I update the field (it's just an empty space in my document, until I update the field, then it jumps to e.g. '2').
This is my code for adding the field:
def add_caption_number(self, field_code):
""" Add a caption number for the field
:argument
field_code: [string] the type of field e.g. 'Figure', 'Table'...
"""
# Set the pointer to the last paragraph (e.g. the 'Figure ' caption text)
run = self.last_paragraph.add_run()
r = run._r
# Add a Figure Number field xml element
fldChar = OxmlElement("w:fldChar")
fldChar.set(qn("w:fldCharType"), "begin")
r.append(fldChar)
instrText = OxmlElement("w:instrText")
instrText.text = " SEQ %s \* ARABIC" % field_code
r.append(instrText)
fldChar = OxmlElement("w:fldChar")
fldChar.set(qn("w:fldCharType"), "end")
r.append(fldChar)
self.last_paragraph is the last paragraph that has been added and field_code is to select whether to add a Figure or a Table caption number.
I have found an example for updating the fields, but this opens the following window upon opening the document:
def update_fields(save_path):
""" Automatically updates the fields when opening the word document """
namespace = "{http://schemas.openxmlformats.org/wordprocessingml/2006/main}"
doc = DocxTemplate(save_path)
element_updatefields = lxml.etree.SubElement(
doc.settings.element, f"{namespace}updateFields"
)
element_updatefields.set(f"{namespace}val", "true")
doc.save(save_path)
Is there a way to do this without the popup window and without adding macros to the Word document? This needs to work on MacOS and Windows btw.
The behavior described in the question is by design. Updating of fields is a potential security risk - there are some field types that can access external content. Therefore, dynamic content generated outside the Word UI needs user confirmation to update.
I know of only three ways to prevent displaying the prompt
Calculate the values and insert the field result during document generation. The fields will still be updatable, in the normal manner, but won't require updating when the document is opened the first time. (Leave out the code in the second part of the question.)
Use Word Automation Services (requires on-premise SharePoint) to open the document, which will update the fields (as in the second part of the question).
Include a VBA project that performs the field update in an AutoOpen macro. This, of course, means the document type must be macro-enabled (docm) and that macros are allowed to execute on the target installation (also a security risk, of course).
I'm new to Python and I'm trying to make a simple bulletin board system app using web2py. I am trying to add a post into a certain board and I linked the post and board by including the following field in my post table: Field('board_id', db.board). When I try to create a post inside a particular board it gives me an error: "OperationalError: no such column: board.id". My code for create_posts:
def add_post():
board = db.board(request.args(0))
form = SQLFORM(db.post)
db.pst.board_id.default = db.board.id
if form.process().accepted:
session.flash = T('The data was inserted')
redirect(URL('default', 'index'))
return dict(form=form, board=board)
When I try to do {{=board}} on the page that shows the posts in a certain board, I get Row {'name': 'hi', 'id': 1L, 'pst': Set (pst.board_id = 1), 'description': 'hi'} so I know it's there in the database. But when I do the same thing for the "add post" form page, it says "board: None". I'm extremely confused, please point me in the right direction!
There appear to be several problems with your function. First, you are assigning the default value of the board_id field to be a Field object (i.e., db.board.id) rather than an actual id value (e.g., board.id). Second, any default values should be assigned before creating the SQLFORM.
Finally, you pass db.post to SQLFORM, but in the next line, the post table appears to be called db.pst -- presumably these are not two separate tables and one is just a typo.
Regarding the issue of {{=board}} displaying None, that indicates that board = db.board(request.args(0)) is not retrieving a record, which would be due to request.args(0) itself being None or being a value that does not match any record id in db.board. You should check how you are generating the links that lead to add_post and confirm that there is a valid db.board id in the first URL arg. In any case, it might be a good idea to detect when there is no valid board record and either redirect or display an error message.
So, your function should look something like this:
def add_post():
board = db.board(request.args(0)) or redirect(URL('default', 'index'))
db.pst.board_id.default = board.id
form = SQLFORM(db.pst)
if form.process(next=URL('default', 'index'),
message_onsuccess=T('The data was inserted'))
return dict(form=form, board=board)
Note, if your are confident that links to add_post will include valid board IDs, then you can eliminate the first line altogether, as there is no reason to retrieve a record based on its ID if the only field you need from it is the ID (which you already have). Instead, the second line could be:
db.pst.board_id.default = request.args(0) or redirect(URL('default', 'index'))