Get author_id from mail_message in openERP - python

I'm trying to get a field from openERPs mail_message model using python code which is executed in a server action (so its not a module where I can debug! I cannot even print in this state) (when a new eMail is being fetched) but I am unable to get anything useful from it.
Basicly when someone is throwing me a email, a new Task is created by openERP. But the newely created ticket is not connected to the user which send me the mail.
When a new email is fetched, this server action gets executed.
In a table called mail_message you can then find the email (+ author_id, + email, + res_id (which is the id of the created Task), therefore I'd like to fetch the author_id from that table.
(A query would look like this:
SELECT author_id FROM mail_message WHERE type = 'email' AND res_id = '<Task.id>')
This is my current code
#Initialize object. That one points to the mail_message model.
mailMessage_obj = self.pool.get('mail.message')
#Created Id in project_task
myId = object.id
#browse whole object with that id
#message = mailMessage_obj.browse(cr,uid,[myId])
#Select field where
messageIds = mailMessage_obj.search(cr,uid,[('type','=','email'),('res_id','=',myId)],context=context)
if messageIds:
#messageRecord = mailMessage_obj.browse(cr,uid,[myId],context=context)
#object.write({'partner_id':messageRecord.author_id.id})
res = mailMessage_obj.read(messageIds, ['author_id'])
partnerId = res[0]
#Author id
#partnerId = message[0]['author_id']
#partnerId = message.author_id
#res = [(r['id'], r['author_id']) for r in messageRecord]
#partnerId = res
#partnerId = 259866
object.write({'partner_id':partnerId})
I dont know how to get my hands on the author_id properly. If I hardcode a ID and let it write to the database (last two lines) It'll work just fine, but I cant hardcode a users id. ;)
Could someone explain to me how its done correctly?
I dont know whether I should use .browse or .read or something else..

I think you have an error on you python method.
you wrote :
res = mailMessage_obj.read(messageIds, ['author_id'])
partnerId = res[0]
But read() method returns here a list of dict (because messageIds is a list). Then, you have not specified the field you wanted to retrieve from res variable, and finally, as author_id is a many2one, it returns something like this : (2, 'myusers').
You should have done :
res = mailMessage_obj.read(cr, uid, messageIds, ['author_id'])
partnerId = res[0]['author_id'][0]
Hope i helped you,
Greatings

Related

How can I access Json attribute and check if (key)exist in payload or not using python

This is my UI
End user can able to update Summary or my_story one at a time, This is my endpoint URL http:localhost:3000/api/account/profile, once user update any one of the field, the URL will work
This is Request payload for summary field
If the user update the Summary field the above endpoint URL will work.
This is Request payload for my_story field
If the user update the my_story field the above endpoint URL will work.
My code(Once the user update anyone of the field. I want to check which field is updated, for this how can I check whether the user is updated Summary or my_story,after accessing the field I want to sanitize the field and send it to response below one is my code):
from lxml.html import clean
def account_update():
data = json.loads(request.data)
cleaner = clean.Cleaner()
if data['other_details']['summary']:
clean_overview = (data['other_details']['summary'])
sanitized_html = cleaner.clean_html(clean_overview)
else:
clean_overview = (data['other_details']['my_story'])
sanitized_html = cleaner.clean_html(clean_overview)
return jsonify({"account": data})
Guys , in the above code I am getting the request payload as data, after that I am accessing the summary and my_story fields as data['other_details']['summary'] and data['other_details']['summary'], here I wrote if condition to check if the user update summary field if condition will work suppose user update my_story field it will goes to else part, but in my case if I update my_story field getting error.
Error:
if data['other_details']['summary']:
KeyError: 'summary'
NOTE:
Sanitizing the field is working fine (I mean cleaner = clean.Cleaner() and sanitized_html = cleaner.clean_html(clean_overview), I just want to know which field the user is updating. Please help me guys.
Most likely, the request.data doesn't always have the summary field in data['other_details'].
This means, you have to check for it in you if-else block before trying to access it.
Best to check for other_details as well.
Here is one way of doing this:
from lxml.html import clean
def account_update():
data = json.loads(request.data)
cleaner = clean.Cleaner()
if 'other_details' in data:
other_details = data['other_details']
if 'summary' in other_details:
clean_overview = other_details['summary']
sanitized_html = cleaner.clean_html(clean_overview)
elif 'my_story' in other_details:
clean_overview = other_details['my_story']
sanitized_html = cleaner.clean_html(clean_overview)
return jsonify({"account": data})
What i see your program just can't find summary atribute.
Solution 1
Im not sure this will work but function getattr() can help you.
Change this line
data['other_details']['summary']
To this
getattr(getattr(data,'other_details'),'summary', False)
Here you can learn more about getattr()
What is getattr() exactly and how do I use it?
Solution 2
Just use some try: and except:

web2py: How to execute instructions before delete using SQLFORM.smartgrid

I use SQLFORM.smartgrid to show a list of records from a table (service_types). In each row of the smartgrid there is a delete link/button to delete the record. I want to executive some code before smartgrid/web2py actually deletes the record, for example I want to know if there are child records (services table) referencing this record, and if any, flash a message telling user that record cannot be deleted. How is this done?
db.py
db.define_table('service_types',
Field('type_name', requires=[IS_NOT_EMPTY(), IS_ALPHANUMERIC()]),
format='%(type_name)s',
)
db.define_table('services',
Field('service_name',requires=[IS_NOT_EMPTY(),IS_NOT_IN_DB(db,'services.service_name')]),
Field('service_type','reference service_types',requires=IS_IN_DB(db,db.service_types.id,
'%(type_name)s',
error_message='not in table',
zero=None),
ondelete='RESTRICT',
),
Field('interest_rate','decimal(15,2)',requires=IS_DECIMAL_IN_RANGE(0,100)),
Field('max_term','integer'),
auth.signature,
format='%(service_name)s',
)
db.services._plural='Services'
db.services._singular='Service'
if db(db.service_types).count() < 1:
db.service_types.insert(type_name='Loan')
db.service_types.insert(type_name='Contribution')
db.service_types.insert(type_name='Other')
controller
def list_services():
grid = SQLFORM.smartgrid(db.services
, fields = [db.services.service_name,db.services.service_type]
)
return locals()
view
{{extend 'layout.html'}}
{{=grid}}
There are two options. First, the deletable argument can be a function that takes the Row object of a given record and returns True or False to indicate whether the record is deletable. If it returns False, the "Delete" button will not be shown for that record, nor the delete operation be allowed on the server.
def can_delete(row):
return True if [some condition involving row] else False
grid = SQLFORM.smartgrid(..., deletable=can_delete)
Second, there is an ondelete argument that takes the db Table object and the record ID. It is called right before the delete operation, so to prevent the delete, you can do a redirect within that function:
def ondelete(table, record_id):
record = table(record_id)
if [some condition]:
session.flash = 'Cannot delete this record'
redirect(URL())
grid = SQLFORM.smartgrid(..., ondelete=ondelete)
Note, if the grid is loaded via an Ajax component and its actions are therefore performed via Ajax, using redirect within the ondelete method as shown above will not work well, as the redirect will have no effect and the table row will still be deleted from the grid in the browser (even though the database record was not deleted). In that case, an alternative approach is to return a non-200 HTTP response to the browser, which will prevent the client-side Javascript from deleting the row from the table (the delete happens only on success of the Ajax request). We should also set response.flash instead of session.flash (because we are not redirecting/reloading the whole page):
def ondelete(table, record_id):
record = table(record_id)
if [some condition]:
response.flash = 'Cannot delete this record'
raise HTTP(403)
Note, both the deletable and ondelete arguments can be dictionaries with table names as keys, so you can specify different values for different tables that might be linked from the smartgrid.
Finally, notice the delete URLs look like /appname/list_services/services/delete/services/[record ID]. So, in the controller, you can determine if a delete is being requested by checking if 'delete' in request.args. In that case, request.args[-2:] represents the table name and record ID, which you can use to do any checks.
From Anthony's answer I chose the second option and came up with the following:
def ondelete_service_type(service_type_table, service_type_id):
count = db(db.services.service_type == service_type_id).count()
if count > 0:
session.flash = T("Cant delete")
#redirect(URL('default','list_service_types#'))
else:
pass
return locals()
def list_service_types():
grid = SQLFORM.smartgrid(db.service_types
, fields = [db.service_types.type_name, db.services.service_name]
, ondelete = ondelete_service_type
)
return locals()
But, if I do this...
if count > 0:
session.flash = T("Cant delete")
else:
pass
return locals()
I get this error:
And if I do this:
if count > 0:
session.flash = T("Cant delete")
redirect(URL('default','list_service_types#')) <== please take note
else:
pass
return locals()
I get the flash error message Cant delete but the record appears deleted from the list, and reappears after a page refresh with F5 (apparently because the delete was not allowed in the database, which is intended).
Which one should I fix and how?
Note
If any of these issue is resolved I can accept Anthony's answer.

Google app engine - Order listed item

I need your help to order listed item.
I am trying to make apps that can send message to his/her friends ( just like social feeds ). After watching Bret Slatkin talk about create microblogging here's my code:
class Message(ndb.Model):
content = ndb.TextProperty()
created = ndb.DateTimeProperty(auto_now=True)
class MessageIndex(ndb.Model):
receivers = ndb.StringProperty(repeated=True)
class BlogPage(Handler):
def get(self):
if self.request.cookies.get("name"):
user_loggedin = self.request.cookies.get("name")
else:
user_loggedin = None
receive = MessageIndex.query(MessageIndex.receivers == user_loggedin)
receive = receive.fetch()
message_key = [int(r.key.parent().id()) for r in receive]
messages = [Message.get_by_id(int(m)) for m in message_key]
for message in messages:
self.write(message)
The first I do a query to get all message that has my name in the receivers. MessageIndex is child of Message, then I can get key of all message that I receive. And the last is I iter get_by_id using list of message key that I get.
This works fine, but I want to filter each message by its created datetime and thats the problem. The final output is listed item, which cant be ordered using .order or .filter
Maybe some of you can light me up.
You can use the message keys in an 'IN' clause in the Message query. Note that you will need to use the parent() key value, not the id() in this case.
eg:
# dtStart, dtEnd are datetime values
message_keys = [r.key.parent() for r in receive]
query = Message.query(Message._key.IN(message_keys), Message.created>dtStart, Message.created<dtEnd)
query = query.order(Message.created) # or -Message.created for desc
messages = query.fetch()
I am unsure if you wish to simply order by the Message created date, or whether you wish to filter using the date. Both options are catered for above.

Search deleted users/groups in AD with python-ldap

If you delete an user or group in windows AD, it will in "DElETE objects".
I want to use python ldap lib to get them.
Code:
<code>
import ldap
uri = "ldap://10.64.74.17"
user = "XXXXXXXXXX"
password = "XXXXXXXXXXXX"
ldap.set_option(ldap.OPT_REFERRALS, 0)
ldap.set_option(ldap.OPT_NETWORK_TIMEOUT, 5)
ldap.protocol_version = 3
ldapClient = ldap.initialize(uri)
ldapClient.simple_bind_s(user, password)
filter = "(&(objectclass=person)(isDeleted=true)(!(objectclass=computer)))"
results = ldapClient.search_s("DC=xx,DC=com", ldap.SCOPE_SUBTREE,filter)
for result in results:
print result
ldapClient.unbind_s()
</code>
It can't show deleted objects.
What's wrong with this code?
You need to add an ldap control to your search : create the request control for the particular operation, and then pass a collection of controls to your search request as an optional parameter.
In your case, this OID for AD is 1.2.840.113556.1.4.417.
LDAP_SERVER_SHOW_DELETED_OID : 1.2.840.113556.1.4.417
Used with an LDAP operation to specify that tombstones and deleted-objects are visible to the operation.
tombstone_control = ('1.2.840.113556.1.4.417',criticality=1)
results = ldapClient.search_s("DC=xx,DC=com", ldap.SCOPE_SUBTREE,filter, [tombstone_control])
You can also scope your search base to CN=Deleted Objects, DC=xx,DC=com as this is where all deleted objects end up. You should make sure your deleted objects are there first. You can use ldp.exe to check.

Django Query doesn't match

I have the following Django Model:
class State(models.Model):
name = models.CharField(max_length=80,null=False)
latitude = models.CharField(max_length=80,null=False)
longitude = models.CharField(max_length=80,null=False)
def __unicode__(self):
return self.name
In my views.py file I've created the following method:
def getCoords(request):
if request.is_ajax():
if request.method == 'POST':
try:
state = request.POST['state'] #receives the state from JS
stateInstance = State.objects.get(name=state)
stateLat = stateInstance.latitude
stateLong = stateInstance.longitude
data = {"lat" : stateLat, "long" : stateLong}
except State.DoesNotExist:
return HttpResponse("No record")
return HttpResponse(simplejson.dumps(data)) #returns json
So I'm sending this method a param through ajax, let's say "California". The state variable gets the value (I have proved that) but the query doesn't get executed, it returns the query doesn't match message. I've tried with the following as well:
state = request.POST['state']
if state == 'California':
return HttpResponse("Yes!")
else:
return HttpResponse(state)
When this snippet returns the state it displays California which means state's value is correct but the query is not executed properly. I don't know what's going on. Any thoughts?
Make sure you're connecting to the correct database in your settings.py. Make sure the record actually does exist with plain old SQL.
SELECT * FROM [app_name]_state WHERE name = 'California';
Also, try it from the Django shell. python manage.py shell
>>> from [app_name].models import State
>>> s = State.objects.get(name='California')
>>> s
<State: California>
Make sure that what is actually being sent is sent as POST, and not accidentally a GET variable in the URL. Also, make sure that the post variable has no extra characters and that it is actually valid. A decent way to do that is to just print it to the console, or if AJAX, with Firebug.
# Single quotes added so you can see any extra spaces in the console
print "'%s'" % state

Categories

Resources