[REF] Refactoring according to CHS and AL review

bzr revid: jke@openerp.com-20140113174157-ins4vf57g0p6v82u
This commit is contained in:
jke-openerp 2014-01-13 18:41:57 +01:00
parent 656f8241d5
commit c5791441c4
15 changed files with 237 additions and 312 deletions

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# OpenERP, Open Source Business Applications
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@ -15,10 +15,10 @@
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import models
from . import calendar
import controllers
import contacts

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
# OpenERP, Open Source Business Applications
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
# OpenERP, Open Source Business Applications
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@ -33,9 +33,10 @@ from openerp import tools, SUPERUSER_ID
from openerp.osv import fields, osv
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
from openerp.tools.translate import _
from openerp import http
from openerp.http import request
import logging
_logger = logging.getLogger(__name__)
@ -295,7 +296,7 @@ class calendar_attendee(osv.Model):
class res_partner(osv.Model):
_inherit = 'res.partner'
_columns = {
'cal_last_notif': fields.datetime('Last Notification from base Calendar'),
'calendar_last_notif': fields.datetime('Last Notification from base Calendar'),
}
def get_attendee_detail(self, cr, uid, ids, meeting_id, context=None):
@ -312,13 +313,13 @@ class res_partner(osv.Model):
datas.append(data)
return datas
def update_cal_last_event(self, cr, uid, context=None):
def calendar_last_event(self, cr, uid, context=None):
partner = self.pool['res.users'].browse(cr, uid, uid, context=context).partner_id
self.write(cr, uid, partner.id, {'cal_last_notif': datetime.now()}, context=context)
self.write(cr, uid, partner.id, {'calendar_last_notif': datetime.now()}, context=context)
return
class calendar_alarm_manager(osv.Model):
class calendar_alarm_manager(osv.AbstractModel):
_name = 'calendar.alarm_manager'
def get_next_potential_limit_alarm(self, cr, uid, seconds, notif=True, mail=True, partner_id=None, context=None):
@ -424,86 +425,84 @@ class calendar_alarm_manager(osv.Model):
res.append(alert)
return res
def do_run_scheduler_mail(self, cr, uid, context=None):
self.do_run(cr, uid, type='mail', context=None)
def do_run_next_event(self, cr, uid, context=None):
return self.do_run(cr, uid, type='notif', context=None)
def do_run(self, cr, uid, type, context=None): # Type is 'notif' or 'email'
all_notif = []
if (type == 'notif'):
ajax_check_every_seconds = 300
partner = self.pool['res.users'].browse(cr, uid, uid, context=context).partner_id
all_events = self.get_next_potential_limit_alarm(cr, uid, ajax_check_every_seconds, partner_id=partner.id, mail=False, context=context)
elif (type == 'mail'):
cron = self.pool['ir.cron'].search(cr, uid, [('model', 'ilike', self._name)], context=context)
if cron and len(cron) == 1:
cron = self.pool['ir.cron'].browse(cr, uid, cron[0], context=context)
else:
_logger.exception("Cron for % can't be found !" % self._name)
return
if cron.interval_type == "weeks":
cron_interval = cron.interval_number * 7 * 24 * 60 * 60
elif cron.interval_type == "days":
cron_interval = cron.interval_number * 24 * 60 * 60
elif cron.interval_type == "hours":
cron_interval = cron.interval_number * 60 * 60
elif cron.interval_type == "minutes":
cron_interval = cron.interval_number * 60
elif cron.interval_type == "seconds":
cron_interval = cron.interval_number
if not cron_interval:
_logger.exception("Cron delay for % can not be calculated !" % self._name)
return
all_events = self.get_next_potential_limit_alarm(cr, uid, cron_interval, notif=False, context=context)
def get_next_mail(self,cr,uid,context=None):
cron = self.pool.get('ir.cron').search(cr,uid,[('model','ilike',self._name)],context=context)
if cron and len(cron) == 1:
cron = self.pool.get('ir.cron').browse(cr,uid,cron[0],context=context)
else:
raise ("Cron for " + self._name + " not identified :( !")
for event in all_events:
max_delta = all_events[event]['max_duration']
curEvent = self.pool['crm.meeting'].browse(cr, uid, event, context=context)
if cron.interval_type=="weeks":
cron_interval = cron.interval_number * 7 * 24 * 60 * 60
elif cron.interval_type=="days":
cron_interval = cron.interval_number * 24 * 60 * 60
elif cron.interval_type=="hours":
cron_interval = cron.interval_number * 60 * 60
elif cron.interval_type=="minutes":
cron_interval = cron.interval_number * 60
elif cron.interval_type=="seconds":
cron_interval = cron.interval_number
if not cron_interval:
raise ("Cron delay for " + self._name + " can not be calculated :( !")
all_events = self.get_next_potential_limit_alarm(cr,uid,cron_interval,notif=False,context=context)
for event in all_events: #.values()
max_delta = all_events[event]['max_duration'];
curEvent = self.pool.get('crm.meeting').browse(cr,uid,event,context=context)
if curEvent.recurrency:
bFound = False
LastFound = False
for one_date in self.pool['crm.meeting'].get_recurrent_date_by_event(cr, uid, curEvent, context=context):
in_date_format = datetime.strptime(one_date, '%Y-%m-%d %H:%M:%S')
if (type == 'notif'):
LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, ajax_check_every_seconds, after=partner.cal_last_notif, mail=False, context=context)
elif (type == 'mail'):
LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, cron_interval, notif=False, context=context)
for one_date in self.pool.get('crm.meeting').get_recurrent_date_by_event(cr,uid,curEvent, context=context) :
in_date_format = datetime.strptime(one_date, '%Y-%m-%d %H:%M:%S');
LastFound = self.do_check_alarm_for_one_date(cr,uid,in_date_format,curEvent,max_delta,cron_interval,notif=False,context=context)
if LastFound:
for alert in LastFound:
if (type == 'notif'):
all_notif.append(self.do_notif_reminder(cr, uid, alert, context=context))
elif (type == 'mail'):
self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, cron_interval, notif=False, context=context)
self.do_mail_reminder(cr,uid,alert,context=context)
if not bFound: # if it's the first alarm for this recurrent event
bFound = True
if bFound and not LastFound: # if the precedent event had alarm but not this one, we can stop the search for this event
if bFound and not LastFound: # if the precedent event had an alarm but not this one, we can stop the search for this event
break
else:
in_date_format = datetime.strptime(curEvent.date, '%Y-%m-%d %H:%M:%S')
if (type == 'notif'):
LastFound = self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, ajax_check_every_seconds, partner.cal_last_notif, mail=False, context=context)
elif (type == 'mail'):
self.do_check_alarm_for_one_date(cr, uid, in_date_format, curEvent, max_delta, cron_interval, notif=False, context=context)
in_date_format = datetime.strptime(curEvent.date, '%Y-%m-%d %H:%M:%S');
LastFound = self.do_check_alarm_for_one_date(cr,uid,in_date_format,curEvent,max_delta,cron_interval,notif=False,context=context)
if LastFound:
for alert in LastFound:
if (type == 'notif'):
all_notif.append(self.do_notif_reminder(cr, uid, alert, context=context))
elif (type == 'mail'):
all_notif.append(self.do_mail_reminder(cr, uid, alert, context=context))
return all_notif
self.do_mail_reminder(cr,uid,alert,context=context)
def get_next_notif(self,cr,uid,context=None):
ajax_check_every_seconds = 300
partner = self.pool.get('res.users').browse(cr,uid,uid,context=context).partner_id;
all_notif = []
all_events = self.get_next_potential_limit_alarm(cr,uid,ajax_check_every_seconds,partner_id=partner.id,mail=False,context=context)
for event in all_events: # .values()
max_delta = all_events[event]['max_duration'];
curEvent = self.pool.get('crm.meeting').browse(cr,uid,event,context=context)
if curEvent.recurrency:
bFound = False
LastFound = False
for one_date in self.pool.get("crm.meeting").get_recurrent_date_by_event(cr,uid,curEvent, context=context) :
in_date_format = datetime.strptime(one_date, '%Y-%m-%d %H:%M:%S');
LastFound = self.do_check_alarm_for_one_date(cr,uid,in_date_format,curEvent,max_delta,ajax_check_every_seconds,after=partner.cal_last_notif,mail=False,context=context)
if LastFound:
for alert in LastFound:
all_notif.append(self.do_notif_reminder(cr,uid,alert,context=context))
if not bFound: #if it's the first alarm for this recurrent event
bFound = True
if bFound and not LastFound: #if the precedent event had alarm but not this one, we can stop the search fot this event
break
else:
in_date_format = datetime.strptime(curEvent.date, '%Y-%m-%d %H:%M:%S');
LastFound = self.do_check_alarm_for_one_date(cr,uid,in_date_format,curEvent,max_delta,ajax_check_every_seconds,partner.cal_last_notif,mail=False,context=context)
if LastFound:
for alert in LastFound:
all_notif.append(self.do_notif_reminder(cr,uid,alert,context=context))
return all_notif
def do_mail_reminder(self, cr, uid, alert, context=None):
if context is None:
context = {}
@ -913,10 +912,8 @@ class crm_meeting(osv.Model):
return {'value': value}
def new_invitation_token(self, cr, uid, record, partner_id):
db_uuid = self.pool['ir.config_parameter'].get_param(cr, uid, 'database.uuid')
invitation_token = hashlib.sha256('%s-%s-%s-%s-%s' % (time.time(), db_uuid, record._name, record.id, partner_id)).hexdigest()
return invitation_token
def new_invitation_token(self, cr, uid, record, partner_id):
return uuid.uuid4().hex
def create_attendees(self, cr, uid, ids, context):
user_obj = self.pool['res.users']
@ -1223,15 +1220,15 @@ class crm_meeting(osv.Model):
def get_attendee(self, cr, uid, meeting_id, context=None):
# Used for view in controller
invitation = {'meeting': {}, 'attendee': [], 'logo': ''}
company_logo = self.pool['res.users'].browse(cr, uid, uid, context=context).company_id.logo
invitation = {'meeting': {}, 'attendee': []}
meeting = self.browse(cr, uid, int(meeting_id), context)
invitation['meeting'] = {
'event': meeting.name,
'where': meeting.location,
'when': meeting.display_time
}
invitation['logo'] = company_logo.replace('\n', '\\n') if company_logo else ''
for attendee in meeting.attendee_ids:
invitation['attendee'].append({'name': attendee.cn, 'status': attendee.state})
return invitation
@ -1454,30 +1451,6 @@ class crm_meeting(osv.Model):
return result and result[0] or False
return result
def count_left_instance(self, cr, uid, event_id, context=None):
event = self.browse(cr, uid, event_id, context=context)
if event.recurrent_id and event.recurrent_id > 0:
parent_event_id = event.recurrent_id
else:
parent_event_id = event.id
domain = ['|', ('id', '=', parent_event_id), ('recurrent_id', '=', parent_event_id)]
count = self.search(cr, uid, domain, context=context)
return len(count)
def get_linked_ids(self, cr, uid, event_id, show_unactive=True, context=None):
event = self.browse(cr, uid, event_id, context=context)
if event.recurrent_id and event.recurrent_id > 0:
parent_event_id = event.recurrent_id
else:
parent_event_id = event.id
domain = ['|', ('id', '=', parent_event_id), ('recurrent_id', '=', parent_event_id)]
if show_unactive:
domain += ['|', ('active', '=', True), ('active', '=', False)]
return super(crm_meeting, self).search(cr, uid, domain, context=context)
def unlink(self, cr, uid, ids, unlink_level=0, context=None):
if not isinstance(ids, list):
ids = [ids]
@ -1544,8 +1517,33 @@ class ir_attachment(osv.Model):
if isinstance(vals.get('res_id'), str):
vals['res_id'] = get_real_ids(vals.get('res_id'))
return super(ir_attachment, self).write(cr, uid, ids, vals, context=context)
class ir_http(osv.AbstractModel):
_inherit = 'ir.http'
def _auth_method_calendar(self):
token = request.params['token']
db = request.params['db']
registry = openerp.modules.registry.RegistryManager.get(db)
attendee_pool = registry.get('calendar.attendee')
error_message = False
with registry.cursor() as cr:
attendee_id = attendee_pool.search(cr, openerp.SUPERUSER_ID, [('access_token','=',token)])
if not attendee_id:
error_message = """Invalid Invitation Token."""
elif request.session.uid and request.session.login != 'anonymous':
# if valid session but user is not match
attendee = attendee_pool.browse(cr, openerp.SUPERUSER_ID, attendee_id[0])
user = registry.get('res.users').browse(cr, openerp.SUPERUSER_ID, request.session.uid)
if attendee.partner_id.id != user.partner_id.id:
error_message = """Invitation cannot be forwarded via email. This event/meeting belongs to %s and you are logged in as %s. Please ask organizer to add you.""" % (attendee.email, user.email)
if error_message:
raise BadRequest(error_message)
return True
class invite_wizard(osv.osv_memory):
_inherit = 'mail.wizard.invite'

View File

@ -9,12 +9,6 @@
<field name="description">Warning, a mandatory field has been modified since the creation of this event</field>
<field name="default" eval="False"/>
</record>
<record model="res.request.link" id="request_link_event">
<field name="name">Event</field>
<field name="object">calendar.event</field>
</record>
<record model="calendar.alarm" id="alarm_notif_1">
<field name="name">15 min notif</field>
<field name="duration" eval="15" />
@ -89,7 +83,7 @@
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
<field eval="'calendar.alarm_manager'" name="model" />
<field eval="'do_run_scheduler_mail'" name="function" />
<field eval="'get_next_mail'" name="function" />
<!--<field eval="'(False,)'" name="args" />-->
</record>
@ -113,11 +107,6 @@
<field name="name">Feedback Meeting</field>
</record>
<record model="res.request.link" id="request_link_meeting">
<field name="name">Meeting</field>
<field name="object">crm.meeting</field>
</record>
<record id="calendar_template_meeting_invitation" model="email.template">
<field name="name">Meeting Invitation</field>
<field name="email_from">${object.event_id.user_id.email or ''}</field>
@ -484,6 +473,5 @@
]]>
</field>
</record>
</data>
</openerp>

View File

@ -1,3 +1,24 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Business Applications
# Copyright (c) 2011 OpenERP S.A. <http://openerp.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import fields, osv
class calendar_contacts(osv.osv):

View File

@ -10,28 +10,8 @@ from werkzeug.exceptions import BadRequest
class meeting_invitation(http.Controller):
def check_security(self, db, token):
registry = openerp.modules.registry.RegistryManager.get(db)
attendee_pool = registry.get('calendar.attendee')
error_message = False
with registry.cursor() as cr:
attendee_id = attendee_pool.search(cr, openerp.SUPERUSER_ID, [('access_token','=',token)])
if not attendee_id:
error_message = """Invalid Invitation Token."""
elif request.session.uid and request.session.login != 'anonymous':
# if valid session but user is not match
attendee = attendee_pool.browse(cr, openerp.SUPERUSER_ID, attendee_id[0])
user = registry.get('res.users').browse(cr, openerp.SUPERUSER_ID, request.session.uid)
if attendee.partner_id.user_id.id != user.id:
error_message = """Invitation cannot be forwarded via email. This event/meeting belongs to %s and you are logged in as %s. Please ask organizer to add you.""" % (attendee.email, user.email)
if error_message:
raise BadRequest(error_message)
return True
@http.route('/calendar/meeting/accept', type='http', auth="none")
def accept(self, db, token, action, id):
self.check_security(db, token)
@http.route('/calendar/meeting/accept', type='http', auth="calendar")
def accept(self, db, token, action, id,**kwargs):
registry = openerp.modules.registry.RegistryManager.get(db)
attendee_pool = registry.get('calendar.attendee')
with registry.cursor() as cr:
@ -40,9 +20,8 @@ class meeting_invitation(http.Controller):
attendee_pool.do_accept(cr, openerp.SUPERUSER_ID, attendee_id)
return self.view(db, token, action, id, view='form')
@http.route('/calendar/meeting/decline', type='http', auth="none")
@http.route('/calendar/meeting/decline', type='http', auth="calendar")
def declined(self, db, token, action, id):
self.check_security(db, token)
registry = openerp.modules.registry.RegistryManager.get(db)
attendee_pool = registry.get('calendar.attendee')
with registry.cursor() as cr:
@ -51,9 +30,8 @@ class meeting_invitation(http.Controller):
attendee_pool.do_decline(cr, openerp.SUPERUSER_ID, attendee_id)
return self.view(db, token, action, id, view='form')
@http.route('/calendar/meeting/view', type='http', auth="none")
@http.route('/calendar/meeting/view', type='http', auth="calendar")
def view(self, db, token, action, id, view='calendar'):
self.check_security(db, token)
registry = openerp.modules.registry.RegistryManager.get(db)
meeting_pool = registry.get('crm.meeting')
attendee_pool = registry.get('calendar.attendee')
@ -89,6 +67,6 @@ class meeting_invitation(http.Controller):
uid = request.session.uid
context = request.session.context
with registry.cursor() as cr:
res = registry.get("res.partner").update_cal_last_event(cr,uid,context=context)
res = registry.get("res.partner").calendar_last_event(cr,uid,context=context)
return res

View File

@ -8,12 +8,11 @@ openerp.calendar = function(instance) {
get_notif_box: function(me) {
return $(me).closest(".ui-notify-message-style");
},
get_next_event: function() {
get_next_notif: function() {
var self= this;
this.rpc("/calendar/notify")
.then(
function(result) {
console.log(result);
_.each(result, function(res) {
setTimeout(function() {
//If notification not already displayed, we add button and action on it
@ -49,9 +48,9 @@ openerp.calendar = function(instance) {
},
check_notifications: function() {
var self= this;
self.get_next_event();
self.get_next_notif();
setInterval(function(){
self.get_next_event();
self.get_next_notif();
}, 5 * 60 * 1000 );
},
@ -78,6 +77,7 @@ openerp.calendar = function(instance) {
if(instance.session.session_is_valid(self.db) && instance.session.username != "anonymous") {
self.redirect_meeting_view(self.db,self.action,self.id,self.view);
} else {
alert('in anonymous or null ');
self.open_invitation_form(self.attendee_data);
}
},
@ -87,15 +87,14 @@ openerp.calendar = function(instance) {
redirect_meeting_view : function(db, action, meeting_id, view){
var self = this;
var action_url = '';
if(view == "form") {
action_url = _.str.sprintf('/?db=%s#id=%s&view_type=%s&model=crm.meeting', db, meeting_id, view, meeting_id);
} else {
action_url = _.str.sprintf('/?db=%s#view_type=%s&model=crm.meeting&action=%s',self.db,self.view,self.action);
}
action_url = _.str.sprintf('/?db=%s#id=%s&view_type=form&model=crm.meeting', db, meeting_id);
var reload_page = function(){
return location.replace(action_url);
}
reload_page();
},
});

View File

@ -32,32 +32,45 @@
</t>
<t t-name="invitation_view">
<div class="oe_right"><b><t t-esc="invitation['current_attendee'].cn"/> (<t t-esc="invitation['current_attendee'].email"/>)</b></div>
<div class="oe_left"><img class="cal_inline cal_image" t-attf-src="data:image/png;base64,#{invitation['logo']}"/><p class="cal_tag cal_inline">Calendar</p></div>
<div class="invitation_block">
<t t-if="invitation['current_attendee'].state != 'needsAction'">
<div class="event_status"><a t-attf-class="attendee_#{invitation['current_attendee'].state}"><b t-if="invitation['current_attendee'].state == 'accepted'">Yes I'm going.</b><b t-if="invitation['current_attendee'].state == 'declined'">No I'm not going.</b></a></div>
</t>
<div class="cal_meeting"><t t-esc="invitation['meeting'].event"/></div>
<table calss="invitation_block">
<tr>
<td class="cal_lable">When</td>
<td>: <t t-esc="invitation['meeting'].when"/></td>
</tr>
<tr>
<td class="cal_lable">Where</td>
<td>: <t t-esc="invitation['meeting'].where or '-'"/></td>
</tr>
<tr>
<td class="cal_lable">Who</td>
<td>
<t t-foreach="invitation['attendee']" t-as="att">
<br/>
<span class="cal_status"><a t-attf-class="oe_invitation #{att.status}"/><t t-esc="att.name"/></span>
</t>
</td>
</tr>
</table>
<div class='invitation_block well' style='width:50%; margin:auto; margin-top : 30px;'>
<div class="oe_right"><b><t t-esc="invitation['current_attendee'].cn"/> (<t t-esc="invitation['current_attendee'].email"/>)</b></div>
<div class="oe_left">
<img class="cal_inline cal_image" src='/web/binary/company_logo' />
</div>
<div>
<div class="invitation_block cal_meeting">
<h2 class="cal_inline">Calendar Invitation</h2>
<t t-if="invitation['current_attendee'].state != 'needsAction'">
<a t-attf-class="attendee_#{invitation['current_attendee'].state}">
<b t-if="invitation['current_attendee'].state == 'accepted'">Yes I'm going.</b>
<b t-if="invitation['current_attendee'].state == 'declined'">No I'm not going.</b>
</a>
</t>
<br/><br/>
<div class="cal_meeting"><t t-esc="invitation['meeting'].event"/></div>
<br/>
<table class="">
<tr>
<td class="cal_lable">When</td>
<td> <t t-esc="invitation['meeting'].when"/></td>
</tr>
<tr>
<td class="cal_lable">Where</td>
<td> <t t-esc="invitation['meeting'].where or '-'"/></td>
</tr>
<tr>
<td class="cal_lable">Who</td>
<td>
<t t-foreach="invitation['attendee']" t-as="att">
<br/>
<span class="cal_status"><a t-attf-class="oe_invitation #{att.status}"/><t t-esc="att.name"/></span>
</t>
</td>
</tr>
</table>
<br/>
</div>
</div>
</div>
</t>
</template>

View File

@ -17,18 +17,16 @@ class google_auth(http.Controller):
state = simplejson.loads(kw['state'])
dbname = state.get('d')
service = state.get('s')
url_return = state.get('from')
url_return = state.get('f')
registry = openerp.modules.registry.RegistryManager.get(dbname)
with registry.cursor() as cr:
if kw.get('code',False):
registry.get('google.%s' % service).set_all_tokens(cr,request.session.uid,kw['code'])
return werkzeug.utils.redirect(url_return)
#TODO - Display error at customer if url contains ?Error=
elif kw.get('error'):
return werkzeug.utils.redirect("%s%s%s" % (url_return ,"?Error=" , kw.get('error')))
return werkzeug.utils.redirect("%s%s%s" % (url_return ,"?error=" , kw.get('error')))
else:
return werkzeug.utils.redirect("%s%s%s" % (url_return ,"?Error=Unknown_error"))
return werkzeug.utils.redirect("%s%s%s" % (url_return ,"?error=Unknown_error"))

View File

@ -28,6 +28,8 @@ import urllib
import urllib2
import simplejson
import logging
_logger = logging.getLogger(__name__)
class google_service(osv.osv_memory):
_name = 'google.service'
@ -68,10 +70,7 @@ class google_service(osv.osv_memory):
def _get_authorize_uri(self, cr, uid, from_url, service, scope = False, context=None):
""" This method return the url needed to allow this instance of OpenErp to access to the scope of gmail specified as parameters """
state_obj = {}
state_obj['d'] = cr.dbname
state_obj['s'] = service
state_obj['from'] = from_url
state_obj = dict(d=cr.dbname, s=service, f=from_url)
base_url = self.get_base_url(cr, uid, context)
client_id = self.get_client_id(cr, uid, service, context)
@ -110,10 +109,8 @@ class google_service(osv.osv_memory):
req = urllib2.Request(self.get_uri_oauth(a='token'), data, headers)
content = urllib2.urlopen(req).read()
res = simplejson.loads(content)
res = simplejson.loads(content)
except urllib2.HTTPError,e:
print e
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong during your token generation. Maybe your Authorization Code is invalid"), context=context)
return res
@ -143,19 +140,8 @@ class google_service(osv.osv_memory):
return res
def _do_request(self,cr,uid,uri,params={},headers={},type='POST', context=None):
_logger.debug("Uri: %s - Type : %s - Headers: %s - Params : %s !" % (uri,type,headers,urllib.urlencode(params) if type =='GET' else params))
res = False
######################
### FOR DEBUG ###
######################
# print "#########################################"
# print "### URI : %s ###" % (uri)
# print "### HEADERS : %s ###" % (headers)
# print "### METHOD : %s ###" % (type)
# if type=='GET':
# print "### PARAMS : %s ###" % urllib.urlencode(params)
# else:
# print "### PARAMS : %s ###" % (params)
# print "#########################################"
try:
if type.upper() == 'GET' or type.upper() == 'DELETE':
@ -164,7 +150,7 @@ class google_service(osv.osv_memory):
elif type.upper() == 'POST' or type.upper() == 'PATCH' or type.upper() == 'PUT':
req = urllib2.Request(self.get_uri_api() + uri, params, headers)
else:
raise ('Method not supported [%s] not in [GET, POST, PUT or PATCH]!' % (type))
raise ('Method not supported [%s] not in [GET, POST, PUT, PATCH or DELETE]!' % (type))
req.get_method = lambda: type.upper()
request = urllib2.urlopen(req)
@ -176,11 +162,9 @@ class google_service(osv.osv_memory):
else:
content=request.read()
res = simplejson.loads(content)
print "="
except urllib2.HTTPError,e:
print "ERROR CATCHED : ",e.read()
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong with your request to google"), context=context)
_logger.exception("Bad google request : %s !" % e.read())
raise self.pool.get('res.config.settings').get_config_warning(cr, _("Something went wrong with your request to google"), context=context)
return res
def get_base_url(self, cr, uid, context=None):

View File

@ -14,18 +14,16 @@ class google_calendar_controller(http.Controller):
def sync_data(self, arch, fields, model,**kw):
"""
This route/function is called when we want to synchronize openERP calendar with Google Calendar
Function return a dictionary with the status : NeedConfigFromAdmin, NeedAuth, NeedRefresh, NoNewEventFromGoogle, SUCCESS if not crm meeting
Function return a dictionary with the status : need_config_from_admin, need_auth, need_refresh, success if not crm_meeting
The dictionary may contains an url, to allow OpenERP Client to redirect user on this URL for authorization for example
"""
if model == 'crm.meeting':
gs_obj = request.registry.get('google.service')
gc_obj = request.registry.get('google.calendar')
gs_obj = request.registry['google.service']
gc_obj = request.registry['google.calendar']
# Checking that admin have already configured Google API for google synchronization !
client_id = gs_obj.get_client_id(request.cr, request.uid,'calendar',context=kw.get('LocalContext'))
client_id = gs_obj.get_client_id(request.cr, request.uid,'calendar',context=kw.get('local_context'))
if not client_id or client_id == '':
action = ''
@ -33,21 +31,21 @@ class google_calendar_controller(http.Controller):
dummy, action = request.registry.get('ir.model.data').get_object_reference(request.cr, request.uid, 'google_calendar', 'action_config_settings_google_calendar')
return {
"status" : "NeedConfigFromAdmin",
"status" : "need_config_from_admin",
"url" : '',
"action" : action
}
# Checking that user have already accepted OpenERP to access his calendar !
if gc_obj.need_authorize(request.cr, request.uid,context=kw.get('LocalContext')):
url = gc_obj.authorize_google_uri(request.cr, request.uid, from_url=kw.get('fromurl'), context=kw.get('LocalContext'))
# Checking that user have already accepted OpenERP to access his calendar !
if gc_obj.need_authorize(request.cr, request.uid,context=kw.get('local_context')):
url = gc_obj.authorize_google_uri(request.cr, request.uid, from_url=kw.get('fromurl'), context=kw.get('local_context'))
return {
"status" : "NeedAuth",
"status" : "need_auth",
"url" : url
}
# If App authorized, and user access accepted, We launch the synchronization
return gc_obj.synchronize_events(request.cr, request.uid, [], kw.get('LocalContext'))
return gc_obj.synchronize_events(request.cr, request.uid, [], kw.get('local_context'))
return { "status" : "Success" }
return { "status" : "success" }

View File

@ -22,7 +22,6 @@ import operator
import simplejson
import re
import urllib
import urllib2
import warnings
from openerp import tools
@ -40,7 +39,7 @@ from openerp.osv import osv
class google_calendar(osv.osv):
class google_calendar(osv.AbstractModel):
STR_SERVICE = 'calendar'
_name = 'google.%s' % STR_SERVICE
@ -152,7 +151,6 @@ class google_calendar(osv.osv):
if context['curr_attendee']:
self.pool.get('calendar.attendee').write(cr,uid,[context['curr_attendee']], {'oe_synchro_date':update_date},context)
def update_an_event(self, cr, uid,event, context=None):
gs_pool = self.pool.get('google.service')
@ -178,7 +176,7 @@ class google_calendar(osv.osv):
url = "/calendar/v3/calendars/%s/events/%s?access_token=%s" % ('primary', instance_id,self.get_token(cr,uid,context))
headers = { 'Content-type': 'application/json'}
data['sequence'] = self.get_sequence(cr, uid, instance_id, context)
data_json = simplejson.dumps(data)
return gs_pool._do_request(cr, uid, url, data_json, headers, type='PUT', context=context)
@ -270,8 +268,7 @@ class google_calendar(osv.osv):
self.pool.get('calendar.attendee').write(cr,uid,[context['curr_attendee']], {'oe_synchro_date':update_date,'google_internal_event_id': single_event_dict.get('id',False)},context)
return res
def synchronize_events(self, cr, uid, ids, context=None):
gc_obj = self.pool.get('google.calendar')
@ -283,7 +280,7 @@ class google_calendar(osv.osv):
res = self.update_events(cr, uid, context)
return {
"status" : res and "NeedRefresh" or "NoNewEventFromGoogle",
"status" : res and "need_refresh" or "no_new_event_form_google",
"url" : ''
}
@ -307,8 +304,7 @@ class google_calendar(osv.osv):
att_obj.write(cr, uid, [att.id], {'google_internal_event_id': response['id'], 'oe_synchro_date':update_date})
cr.commit()
return True
def get_empty_synchro_summarize(self) :
return {
#OPENERP
@ -430,8 +426,6 @@ class google_calendar(osv.osv):
event['td_source'] = (event['OE_status'] and "OE") or (event['GG_status'] and "GG")
#If event is not deleted !
elif event['OE_status'] and event['GG_status']:
# if not event['GG_update']:
# print "### Should never be here
if event['OE_update'].split('.')[0] != event['GG_update'].split('.')[0]:
if event['OE_update'] < event['GG_update']:
event['td_source'] = 'GG'
@ -502,7 +496,6 @@ class google_calendar(osv.osv):
# DO ACTION #
######################
for base_event in event_to_synchronize:
#print "Base Event : %s " % base_event
event_to_synchronize[base_event] = sorted(event_to_synchronize[base_event].iteritems(),key=operator.itemgetter(0))
for current_event in event_to_synchronize[base_event]:
cr.commit()
@ -515,13 +508,13 @@ class google_calendar(osv.osv):
# print " Found OE:%5s vs GG: %5s" % (event['OE_found'],event['GG_found'])
# print " Recurrence OE:%5s vs GG: %5s" % (event['OE_isRecurrence'],event['GG_isRecurrence'])
# print " Instance OE:%5s vs GG: %5s" % (event['OE_isInstance'],event['GG_isInstance'])
# print " Synchro OE: %10s " % (event['OE_synchro'])
# print " Synchro OE: %10s " % (event['OE_synchro'])
# print " Update OE: %10s " % (event['OE_update'])
# print " Update GG: %10s " % (event['GG_update'])
# print " Status OE:%5s vs GG: %5s" % (event['OE_status'],event['GG_status'])
# print " Action %s" % (event['td_action'])
# print " Source %s" % (event['td_source'])
# print " comment %s" % (event['td_comment'])
# print " Action %s" % (event['td_action'])
# print " Source %s" % (event['td_source'])
# print " comment %s" % (event['td_comment'])
context['curr_attendee'] = event.get('OE_attendee_id',False)
@ -615,21 +608,7 @@ class google_calendar(osv.osv):
self.update_to_google(cr, uid, oe_event, google_event, context)
elif datetime.strptime(oe_event.oe_update_date,"%Y-%m-%d %H:%M:%S.%f") < datetime.strptime(google_event['updated'],"%Y-%m-%dT%H:%M:%S.%fz"):
self.update_from_google(cr, uid, oe_event, google_event, 'write', context)
def get_sequence(self,cr,uid,instance_id,context=None):
gs_pool = self.pool.get('google.service')
params = {
'fields': 'sequence',
'access_token' : self.get_token(cr,uid,context)
}
headers = {'Content-type': 'application/json'}
url = "/calendar/v3/calendars/%s/events/%s" % ('primary',instance_id)
content = gs_pool._do_request(cr, uid, url, params, headers, type='GET', context=context)
return content.get('sequence',0)
#################################
## MANAGE CONNEXION TO GMAIL ##
@ -684,7 +663,7 @@ class google_calendar(osv.osv):
class res_users(osv.osv):
class res_users(osv.Model):
_inherit = 'res.users'
_columns = {
@ -694,7 +673,7 @@ class res_users(osv.osv):
}
class crm_meeting(osv.osv):
class crm_meeting(osv.Model):
_inherit = "crm.meeting"
def write(self, cr, uid, ids, vals, context=None):
@ -722,7 +701,7 @@ class crm_meeting(osv.osv):
}
class calendar_attendee(osv.osv):
class calendar_attendee(osv.Model):
_inherit = 'calendar.attendee'
_columns = {

View File

@ -1,7 +1,6 @@
from openerp.osv import fields, osv
class calendar_config_settings(osv.osv_memory):
#_name = 'calendar.config.settings'
class calendar_config_settings(osv.TransientModel):
_inherit = 'base.config.settings'
_columns = {
@ -11,33 +10,11 @@ class calendar_config_settings(osv.osv_memory):
'server_uri': fields.char('URI for tuto')
}
def set_calset(self,cr,uid,ids,context=None) :
params = self.pool.get('ir.config_parameter')
me = self.browse(cr,uid,ids[0],context=context)
#new_val = dict(cal_client_id=me.cal_client_id,cal_client_secret=me.cal_client_secret)
new_val_id = {
'key' : 'google_calendar_client_id',
'value' : me.cal_client_id
}
new_val_secret = {
'key' : 'google_calendar_client_secret',
'value' : me.cal_client_secret
}
exist_id = params.search(cr,uid,[('key','=','google_calendar_client_id')],context=context)
exist_secret = params.search(cr,uid,[('key','=','google_calendar_client_secret')],context=context)
if exist_id:
params.write(cr,uid,exist_id[0],new_val_id,context=context)
else:
params.create(cr,uid,new_val_id,context=context)
if exist_secret:
params.write(cr,uid,exist_secret[0],new_val_secret,context=context)
else:
params.create(cr,uid,new_val_secret,context=context)
params = self.pool['ir.config_parameter']
myself = self.browse(cr,uid,ids[0],context=context)
params.set_param(cr, uid, 'google_calendar_client_id', myself.cal_client_id, context=None)
params.set_param(cr, uid, 'google_calendar_client_secret', myself.cal_client_secret, context=None)
def get_default_all(self,cr,uid,ids,context=None):

View File

@ -80,10 +80,7 @@
<field name="view_mode">form</field>
<field name="target">inline</field>
</record>
<!--
<menuitem id="menu_calendar_google_main" parent="base.menu_administration" name="Google Calendar"/>
<menuitem id="menu_calendar_google_config" name="API credentials" parent="google_calendar.menu_calendar_google_main" action="action_config_settings_google_calendar"/>
-->
<menuitem id="menu_calendar_google_tech_config" name="API Credentials" parent="calendar.menu_calendar_configuration" groups="base.group_no_one" action="action_config_settings_google_calendar"/>
</data>

View File

@ -3,11 +3,10 @@ openerp.google_calendar = function(instance) {
_lt = instance.web._lt;
var QWeb = instance.web.qweb;
instance.web_calendar.FullCalendarView.include({
instance.web_calendar.CalendarView.include({
view_loading: function(r) {
var self = this;
this.$el.on('click', 'div.oe_cal_sync_button', function() {
console.log("Launch synchro");
self.sync_calendar(r);
});
return this._super(r);
@ -23,17 +22,15 @@ openerp.google_calendar = function(instance) {
fields: res.fields,
model:res.model,
fromurl: window.location.href,
LocalContext:context
local_context:context
}).done(function(o) {
console.log(o);
if (o.status == "NeedAuth") {
if (o.status == "need_auth") {
alert(_t("You will be redirected on gmail to authorize your OpenErp to access your calendar !"));
window.location = o.url;
instance.web.redirect(o.url);
}
else if (o.status == "NeedConfigFromAdmin") {
else if (o.status == "need_config_from_admin") {
if (typeof o.action !== 'undefined' && parseInt(o.action)) {
if (!_.IsUndefined(o.action) && parseInt(o.action)) {
if (confirm(_t("An admin need to configure Google Synchronization before to use it, do you want to configure it now ? !"))) {
self.do_action(o.action);
}
@ -41,9 +38,8 @@ openerp.google_calendar = function(instance) {
else {
alert(_t("An admin need to configure Google Synchronization before to use it !"));
}
//window.location = o.url;
}
else if (o.status == "NeedRefresh"){
else if (o.status == "need_refresh"){
self.$calendar.fullCalendar('refetchEvents');
}
@ -51,13 +47,12 @@ openerp.google_calendar = function(instance) {
}
});
instance.web_calendar.FullCalendarView.include({
instance.web_calendar.CalendarView.include({
extraSideBar: function() {
this._super();
if (this.dataset.model == "crm.meeting") {
var button = QWeb.render('GoogleCalendar.buttonSynchro');
this.$el.find('.oe_calendar_filter').prepend(button);
}
this.$el.find('.oe_calendar_filter').prepend(QWeb.render('GoogleCalendar.buttonSynchro'));
}
}
});