routing page in Odoo v8 - odoo-8

I received error 404 when try to route similar pages in Odoo8:
class vips_salepage(http.Controller):
#http.route('/salepage/<filialpage>', type='http', auth="public", website=True)
def page(self, filialpage, **kw):
cr, uid, context, registry = request.cr, request.uid, request.context, request.registry
# here my code
return http.request.render('vips_shop.indexpage2', result)
#http.route('/salepage/', type='http', auth="public", website=True)
def page(self, **kw):
cr, uid, context, registry = request.cr, request.uid, request.context, request.registry
# here my code
return http.request.render('vips_shop.filial_list_page', result)
Page /salepage/ displayed sucessfully.
When I try to get /salepage/filialname I receive 404-error.
If I remove
#http.route('/salepage/', type='http', auth="public", website=True)
def page(self, **kw):
cr, uid, context, registry = request.cr, request.uid, request.context, request.registry
# here my code
return http.request.render('vips_shop.filial_list_page', result)
/salepage/filialname displayed ok!
In Odoo v9 all working fine in Odoo v8 i cannot using both routes at the same time.
Why is this happening?

The problem has been successfully resolved.
Error in the same method name under different routes

Related

Discord.py: How do I use #commands.check on an on_message event

I am trying to get the bot to send an emoji when someone else sends one. I have managed to get this to work, but when I use #commands.check to make sure the bot is not responding to itself, it responds anyway and the bot gets stuck in a loop of replying to itself.
def is_it_me_event(message):
if message.author.id == 1234567890:
return False
#commands.Cog.listener("on_message")
#commands.check(is_it_me_event)
async def on_message(self, message):
if str(message.content) == ":smile:":
await message.channel.send(":smile:")
I know I can do this with an if statement inside the function itself, but is there a way of doing this with the commands.check decorator or is this not compatible with functions that aren't commands?
As you suspected, you can't decorate your on_message function with a #commands.check(...) because it isn't a command. However, you can set up a predicate for these events:
def check_author_isnt_self():
def decorator(func):
async def wrapper(message):
return message.author.id != 1234567890:
# or `return message.author.id != self.bot.id` as better practice
return wrapper
return decorator
#commands.Cog.listener("on_message")
#check_author_isnt_self()
async def smile_back(self, message):
if str(message.content) == ":smile:":
await message.channel.send(":smile:")
I got it to work:
def check_author_isnt_self(func):
async def decorator(ctx, *args, **kwargs):
message = args[0]
if message.author.id != 1234567890:
await func(ctx, message)
decorator.__name__ = func.__name__
sig = inspect.signature(func)
decorator.__signature__ = sig.replace(parameters=tuple(sig.parameters.values())[1:])
return decorator
#commands.Cog.listener("on_message")
#check_author_isnt_self
async def on_message(self, message):
if str(message.content) == ":smile:":
await message.channel.send(":smile:")
This article explains how this works: https://scribe.rip/#cantsayihave/decorators-in-discord-py-e44ce3a1aae5

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('🤖')

How do I pytest flask form validators?

I tried everything and I couldn't test the validators. I want to test a flask app that has validators.
This is the code I am trying to test.
class Createform(FlaskForm):
name = StringField('Name:', validators=[DataRequired(), Length(min=2, max=50)])
submit = SubmitField('Submit')
def validate_name(self, name):
name = Chef.query.filter_by(name=name.data).first()
if name:
raise ValidationError ('This name is taken')
I also could not test the following;
#app.route('/createchef', methods = ['POST','GET'])
def createchef():
createform = Createform()
if createform.validate_on_submit():
chef = Chef(name=createform.name.data)
db.session.add(chef)
db.session.commit()
return redirect(url_for('read'))
return render_template('createchef.html', form=createform)

Shared state between WebSocketHandler and RequestHandler

I am writing chat app and I need session data in my websocket handler. Problem is that login and logout is done by AJAX request, and updating/clearing cookie cannot be seen by websocket handler - it sees only state from the time website was initially rendered. But it cannot see, when cookie is changed by AJAX request. Do you have any idea, how this can be implemented?
import json
import tornado.web
import tornado.websocket
class BaseHandler(object):
#property
def db(self):
return self.application.db
def get_current_user(self):
id = self.get_secure_cookie('user')
user = self.db.get_user_by_id(id) if id else ''
return user
class JsonHandler(BaseHandler, tornado.web.RequestHandler):
def write(self, response):
if response:
response = json.dumps(response)
TemplateHandler.write(self, response)
#property
def body(self):
return json.loads(self.request.body.decode())
class WebSocketHandler(BaseHandler, tornado.websocket.WebSocketHandler):
pass
class Login(JsonHandler):
def post(self):
login = self.body.get('login')
password = self.body.get('password')
user = self.db.validate_user(login, password)
if user:
self.set_secure_cookie('user', str(user['id']))
self.write(user)
else:
raise tornado.web.HTTPError(401)
class Logout(JsonHandler):
def post(self):
self.clear_cookie('user')
self.write('')
class WebSocket(WebSocketHandler):
clients = set()
def open(self):
WebSocket.clients.add(self)
def on_close(self):
WebSocket.clients.remove(self)
def on_message(self, message):
# how to use method self.get_current_user()
# it uses self.get_secure_cookie('user')
# but it is not updated dynamically by Login and Logout handlers
# because websocket does not share state with them
for client in WebSocket.clients:
client.write_message(message)

Pylons, FormEncode and external 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)

Resources