Pylons, FormEncode and external validation - validation

I'm building a web frontend to a server-side application, using Pylons 1.0.
Right now I'm writing the first form, and I'm facing a problem concerning validation.. Using FormEncode and the #validate decorator I can easily validate the user input from a client-side perspective, but when I submit the data to the server, it may perform additional checks and eventually throw back exceptions that I need to show to the user.
My question: is there a concise way to integrate/emulate this exception handling into the FormEncode/validate flow? For example, redisplay the form with filled fields and an error message, as would happen if the exception had come from the #validate itself?
Here's what I have at the moment:
def edit(self, id):
return render('/edit_user.mako')
#validate(schema=form.UserForm(), form="edit")
def add_user(self):
if request.POST:
u = helpers.load_attributes(User(), self.form_result)
try:
model.save_to_server(u)
except MyBaseException, exc:
helpers.flash(unicode(exc))
return self.edit()
In this way, in case of a server-side exception I can see the "flash" message but the form of course will have empty fields :/

I like to implement:
from formencode import htmlfill
def create(self):
if request.params:
try:
Post.validate(request.paramse)
post = helpers.load_attributes(Post(), request.params)
model.save_to_server(post)
flash('OK', 'success')
redirect(...)
except InvalidException as e:
for key, message in e.unpack_errors().iteritems():
flash(message, 'error')
return htmlfill.render(render('/blogs/create.html'), request.params)
where my Post.validate:
#staticmethod
def validate(data):
schema = PostSchema()
schema.to_python(data)
In this way, if is the first time (request.params empty) html fills form with nothing, when user send datas html fills form with request.params

Another way (inspired by this answer) is to write a decorator similar to #validate that would catch the desired exceptions and use htmlfill to display their message:
def handle_exceptions(form):
def wrapper(func, self, *args, **kwargs):
try:
return func(self, *args, **kwargs)
except MyBaseException, e:
request = self._py_object.request
errors = { "exception" : unicode(e) }
params = request.POST
decoded = params.mixed()
request.environ['REQUEST_METHOD'] = 'GET'
self._py_object.tmpl_context.form_errors = errors
request.environ['pylons.routes_dict']['action'] = form
response = self._dispatch_call()
# If the form_content is an exception response, return it
if hasattr(response, '_exception'):
return response
htmlfill_kwargs2 = {}
htmlfill_kwargs2.setdefault('encoding', request.charset)
return htmlfill.render(response, defaults=params, errors=errors,
**htmlfill_kwargs2)
return decorator(wrapper)
The decorator would be used like:
#handle_exceptions("edit")
#validate(schema=form.UserForm(), form="edit")
def add_user(self):
if request.POST:
u = helpers.load_attributes(User(), self.form_result)
model.save_to_server(u)

Related

How do you add a reaction to the response of a slash command?

I'm facing problems trying to add a reaction to the bot's response when it responds to a slash command I entered.
#bot.slash_command(name='test', description="Test.")
async def test(ctx):
msg = await ctx.send("Hello.")
await msg.add_reaction('🤖')
As you can see it's supposed to add a reaction to it's own message.
But I get this error:
nextcord.errors.ApplicationInvokeError: Command raised an exception: AttributeError: 'PartialInteractionMessage' object has no attribute 'add_reaction'
Please tell me how do I add a reaction to a slash command.
Explanation
As per the error, ctx.send is returning a PartialInteractionMessage. From the docs:
This does not support most attributes and methods of nextcord.Message. The fetch() method can be used to retrieve the full InteractionMessage object.
Code
#bot.slash_command(name='test', description="Test.")
async def test(ctx):
msg = await ctx.send("Hello.")
full_msg = await msg.fetch()
await full_msg.add_reaction('🤖')

can't loop function in websockets

I trying to use websockets to receive real time update on trading orders. If it sent "closed" then to run some function.
The problem is It only run in "one time". I have tried but still in the dark.
EDIT. I try to make it in class but I don't know why I can't pass variable(self.status) to another function pending(self) in same class
class check:
async def handler(self):
async with websockets.connect('wss://ftx.com/ws/') as ws:
# authentication things
async for data in ws:
message = json.loads(data)
search = dictpy.DictSearch(data=message, target='closed')
self.status = search.result
print(self.status) # It contain 'closed'
async def pending(self):
print(self.status) # but It didn't even recieve from handler
if self.status == [['data.status', {'status': 'closed'}]]:
t3.start()
t4.start()
t3.join()
t4.join()

Discord.py sending an embed without the use of add fields

I am trying to get a message from a user, and then sending it to a specific text channel. The message shall be in an embed. But I don't like how it looks when you have a bunch of fields, I would like the description in the discord.Embed() to hold the text content. But it is giving me an error
TypeError: Object of type Message is not JSON serializable
This is my code:
class Changelog(commands.Cog):
def __init__(self, client):
self.client = client
#commands.Cog.listener()
async def on_ready(self):
print('Changelog is loaded')
#commands.command()
async def changelog(self, ctx):
changelog_channel = self.client.get_channel(759547196433104956)
await ctx.send("`Message: `")
message = await self.client.wait_for('message', check=lambda message: message.author == ctx.author, timeout=300)
embed = discord.Embed(title="Changelog", description=message, color=0)
await changelog_channel.send(embed=embed)
def setup(client):
client.add_cog(Changelog(client))
You're not getting this error because you're not adding fields, but because you're trying to put a message instance in the description, while you should be putting that message's content in there instead. The description can only take strings as it's value.
embed = discord.Embed(title="Changelog", description=message.content, color=0)
wait_for("message") returns a discord.Message instance. A Message holds that message's content, id, author, channel, and way more inside. If you only want to get the text the user sent, you need the content attribute.
More info on what a Message can do can be found in the API docs.

Define Payload Facebook Messenger Ruby

I'm trying to define a 'Payload' in Ruby for my Facebook Messenger bot. My use case is, when a user sees structured content (a story with a button) and they click the button, instead of sending them to a URL, I want to hit my webhook and return more structured content.
So, I've tried several iterations of this and not sure where I'm getting tripped up. I've started by adding a messaging event:
messaging_event["entry"].first["messaging"].each do |msg|
puts msg
sender = msg["sender"]["id"]
if msg["message"] && msg["message"]["text"]
payload = msg["message"][“payload”]
I did something very similar for adding text, which was:
post '/webhook/' do
messaging_event = JSON.parse(request.body.read)
puts messaging_event
messaging_event["entry"].first["messaging"].each do |msg|
puts msg
sender = msg["sender"]["id"]
if msg["message"] && msg["message"]["text"]
text = msg["message"]["text"]
puts "Sender ID: #{sender}, Text: #{text}"
So, at this point, I'm not sure if I need to further def the payload like:
def payload(sender, payload)
data = {
recipient: { id: sender },
message: payload
}
send_message(data)
end
Or, if I simply need to create a variable and call that variable within my Module object like:
module Messages
SIMPLE_ONE_BUTTON_PAYLOAD = {
"attachment":{
"type":"template",
"payload":{
"template_type":"button",
"text":"Here's a simple button message",
"buttons":[
"type":"postback",
"title":"Button One",
"payload":"[variable I need to call]",
]
}
}
}
end
So, there's really two things here -- Do I need the payload messaging event and to define the payload and what do I need to call within the object? Any thoughts or feedback here would be really helpful. Thanks in advance!
You need to handle postbacks in your code. When a user hits a button, facebook calls your webhook with a post back (unless it's a url).
From the docs:
Postbacks are back end calls to your webhook when buttons are tapped. These calls contain the payload that is set for the button. Buttons on Structured Messages support opening URLs and postbacks.
The structure of postback is different than a text message.
Text Message:
{"object":"page","entry":[{"id":654321,"time":1460624758100,"messaging":[{"sender":{"id":123456},"recipient":{"id":654321},"timestamp":1460624758089,"message":{"mid":"mid.987654","seq":12632,"text":"This is the message."}}]}]}
Postback:
{"object":"page","entry":[{"id":654321,"time":1460625294253,"messaging":[{"sender":{"id":123456},"recipient":{"id":654321},"timestamp":1460625294253,"postback":{"payload":"Payload defined in the button"}}]}]}
You're doing if msg["message"] && msg["message"]["text"] but a post back doesn't have the ["message"] element. You need to make another case for msg["postback"].
So, change this:
if msg["message"] && msg["message"]["text"]
payload = msg["message"]["payload"]
to this:
if msg["postback"] && msg["postback"]["payload"]
payload = msg["postback"]["payload"]
You can read further on handling postbacks here in the official documentation (Point 8 Handling Postbacks).

Use Grails Controller to proxy an AJAX request

I have a Javascript component that when the DOM is loaded it needs to send a request out to our CDN, which may be in a different domain, to see if there is content for this component. If there is, the component will self-instantiate (its a link to open an embedded video in a modal), if not it will self destruct. My question is mainly about the Grails controller I am using to proxy the AJAX request.
Here is the JS in pseudocode:
checkForVideoAssets: function(videoDataUrl){
Ajax.get(videoDataUrl, function(data){
if(data.responseText==='error'){
//tear down the component
}
else{
//if there is data for the video instantiate the component
}
Here is the Grails controller:
def checkForModalVideoAsset = {
def req = new URL("http://" + params.videoUrl + "/expense/videos/")
def connection = req.openConnection()
if(connection.responseCode != 200){
render 'error'
}
if(connection.responseCode == 200){
render req.getText()
}
}
So, to sum up, the JS grabs an attribute from the DOM that has part of a URL (that we define by convention), sends that URL to the controller, the controller attempts to connect to that URL (at our CDN) and then passes that response back to the AJAX success callback inside the responseText part of the XHR object. This feels less than ideal to me, is it possible to pass the actual response back up to the JS function?
The httpbuilder may be usefull to you
I never tried it but something similar!?
def checkForModalVideoAsset = {
def http = new HTTPBuilder("http://" + params.videoUrl )
http.get(
path : "/expense/videos/",
contentType : TEXT ) { resp, reader ->
response.properties=resp.properties //<-- to easy to work but why not try :)
response << resp
}
}

Resources