2012-03-02 10:35:05 +00:00
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2012 OpenERP SA (<http://www.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/>.
#
##############################################################################
2012-12-09 18:22:37 +00:00
import logging
2012-11-01 07:18:46 +00:00
from datetime import datetime
2012-12-09 18:22:37 +00:00
2012-12-06 14:56:32 +00:00
from openerp . tools import DEFAULT_SERVER_DATETIME_FORMAT
2013-03-05 13:17:57 +00:00
from openerp import SUPERUSER_ID
2012-12-06 14:56:32 +00:00
from openerp . osv import fields , osv
from openerp . tools . translate import _
2013-03-05 13:17:57 +00:00
from urlparse import urlparse
2012-12-09 18:22:37 +00:00
2013-05-23 10:41:55 +00:00
from httplib2 import Http
import urllib
import json
2012-12-09 18:22:37 +00:00
_logger = logging . getLogger ( __name__ )
2013-05-10 06:35:01 +00:00
class config ( osv . osv ) :
_name = ' google.docs.config '
_description = " Google Drive templates config "
2013-05-23 10:41:55 +00:00
def get_google_doc_name ( self , cr , uid , ids , res_id , tamplate_id , context = None ) :
2013-05-10 06:35:01 +00:00
pool_model = self . pool . get ( " ir.model " )
res = { }
for config in self . browse ( cr , SUPERUSER_ID , ids , context = context ) :
res_model = config . model_id
model_ids = pool_model . search ( cr , uid , [ ( ' model ' , ' = ' , res_model ) ] )
if not model_ids :
continue
model = pool_model . browse ( cr , uid , model_ids [ 0 ] , context = context )
model_name = model . name
filter_name = config . filter_id and config . filter_id . name or False
record = self . pool . get ( res_model ) . read ( cr , uid , res_id , [ ] , context = context )
record . update ( { ' model ' : model_name , ' filter ' : filter_name } )
name_gdocs = config . name_template or " %(name)s _ %(model)s _ %(filter)s _gdrive "
try :
name_gdocs = name_gdocs % record
except :
raise osv . except_osv ( _ ( ' Key Error! ' ) , _ ( " Your Google Doc Name Pattern ' s key does not found in object. " ) )
attach_pool = self . pool . get ( " ir.attachment " )
attach_ids = attach_pool . search ( cr , uid , [ ( ' res_model ' , ' = ' , res_model ) , ( ' name ' , ' = ' , name_gdocs ) , ( ' res_id ' , ' = ' , res_id ) ] )
url = False
if attach_ids :
attachment = attach_pool . browse ( cr , uid , attach_ids [ 0 ] , context )
url = attachment . url
2013-05-23 10:41:55 +00:00
else :
url = self . copy_doc ( cr , uid , ids , res_id , tamplate_id , name_gdocs , res_model , context )
res [ config . id ] = { ' url ' : url }
return res
def copy_doc ( self , cr , uid , ids , res_id , tamplate_id , name_gdocs , res_model , context = None ) :
ir_config = self . pool [ ' ir.config_parameter ' ]
2013-06-25 10:58:19 +00:00
google_docs_client_id = ir_config . get_param ( cr , SUPERUSER_ID , ' google_docs_client_id ' )
google_docs_client_secret = ir_config . get_param ( cr , SUPERUSER_ID , ' google_docs_client_secret ' )
google_docs_refresh_token = ir_config . get_param ( cr , SUPERUSER_ID , ' google_docs_refresh_token ' )
2013-05-23 10:41:55 +00:00
google_web_base_url = ir_config . get_param ( cr , SUPERUSER_ID , ' web.base.url ' )
#For Getting New Access Token With help of old Refresh Token
headers = { " Content-type " : " application/x-www-form-urlencoded " }
2013-06-25 10:58:19 +00:00
data = dict ( client_id = google_docs_client_id ,
refresh_token = google_docs_refresh_token ,
client_secret = google_docs_client_secret ,
2013-05-23 10:41:55 +00:00
grant_type = " refresh_token " )
data = urllib . urlencode ( data )
resp , content = Http ( ) . request ( " https://accounts.google.com/o/oauth2/token " , " POST " , data , headers )
content = json . loads ( content )
# Copy template in to drive with help of new access token
2013-05-29 07:07:23 +00:00
if content . has_key ( ' access_token ' ) :
2013-05-30 09:46:19 +00:00
request_url = " https://www.googleapis.com/drive/v2/files/ %s ?fields=parents/id&access_token= %s " % ( tamplate_id , content [ ' access_token ' ] )
resp , parents = Http ( ) . request ( request_url , " GET " )
parents_dict = json . loads ( parents )
2013-05-29 07:07:23 +00:00
headers = { ' Content-type ' : ' application/json ' , ' Accept ' : ' text/plain ' }
record_url = " Click on link to open Record in OpenERP \n %s /?db= %s #id= %s &model= %s " % ( google_web_base_url , cr . dbname , res_id , res_model )
2013-05-30 09:46:19 +00:00
data = { " title " : name_gdocs , " description " : record_url , " parents " : parents_dict [ ' parents ' ] }
2013-05-29 07:07:23 +00:00
request_url = " https://www.googleapis.com/drive/v2/files/ %s /copy?access_token= %s " % ( tamplate_id , content [ ' access_token ' ] )
resp , content = Http ( ) . request ( request_url , " POST " , json . dumps ( data ) , headers )
content = json . loads ( content )
res = False
if ' alternateLink ' in content . keys ( ) :
attach_pool = self . pool . get ( " ir.attachment " )
attach_vals = { ' res_model ' : res_model , ' name ' : name_gdocs , ' res_id ' : res_id , ' type ' : ' url ' , ' url ' : content [ ' alternateLink ' ] }
attach_pool . create ( cr , uid , attach_vals )
res = content [ ' alternateLink ' ]
else :
2013-06-04 06:29:48 +00:00
raise self . pool . get ( ' res.config.settings ' ) . get_config_warning ( cr , _ ( " You haven ' t configured ' Authorization Code ' generated from google, Please generate and configure it in % (menu:base_setup.menu_general_configuration)s. " ) , context = context )
2013-05-10 06:35:01 +00:00
return res
2013-05-09 14:10:01 +00:00
2013-04-01 08:03:23 +00:00
def get_google_docs_config ( self , cr , uid , res_model , res_id , context = None ) :
2012-05-23 09:51:36 +00:00
'''
Function called by the js , when no google doc are yet associated with a record , with the aim to create one . It
will first seek for a google . docs . config associated with the model ` res_model ` to find out what ' s the template
of google doc to copy ( this is usefull if you want to start with a non - empty document , a type or a name
different than the default values ) . If no config is associated with the ` res_model ` , then a blank text document
with a default name is created .
: param res_model : the object for which the google doc is created
: param ids : the list of ids of the objects for which the google doc is created . This list is supposed to have
a length of 1 element only ( batch processing is not supported in the code , though nothing really prevent it )
2013-04-01 08:03:23 +00:00
: return : the config id and config name
2012-05-23 09:51:36 +00:00
'''
2013-04-01 08:03:23 +00:00
if not res_id :
2013-02-25 09:16:39 +00:00
raise osv . except_osv ( _ ( ' Google Drive Error! ' ) , _ ( " Creating google drive may only be done by one at a time. " ) )
2013-04-01 08:03:23 +00:00
# check if a model is configured with a template
2013-05-10 06:35:01 +00:00
config_ids = self . search ( cr , uid , [ ( ' model_id ' , ' = ' , res_model ) ] , context = context )
2013-04-01 08:03:23 +00:00
configs = [ ]
2013-05-10 06:35:01 +00:00
for config in self . browse ( cr , SUPERUSER_ID , config_ids , context = context ) :
2013-04-01 08:03:23 +00:00
if config . filter_id :
2013-04-04 07:05:23 +00:00
if ( config . filter_id . user_id and config . filter_id . user_id . id != uid ) :
#Private
continue
2013-04-01 08:03:23 +00:00
google_doc_configs = self . _filter ( cr , uid , config , config . filter_id , res_id , context = context )
2013-03-08 13:30:39 +00:00
if google_doc_configs :
2013-04-01 08:03:23 +00:00
configs . append ( { ' id ' : config . id , ' name ' : config . name } )
2013-03-08 13:30:39 +00:00
else :
2013-04-01 08:03:23 +00:00
configs . append ( { ' id ' : config . id , ' name ' : config . name } )
return configs
2013-03-08 13:30:39 +00:00
2013-04-01 08:03:23 +00:00
def _filter ( self , cr , uid , action , action_filter , record_ids , context = None ) :
2013-03-08 13:30:39 +00:00
""" filter the list record_ids that satisfy the action filter """
records = { }
if record_ids and action_filter :
2013-04-01 08:03:23 +00:00
if not action . model_id == action_filter . model_id :
2013-03-20 05:39:10 +00:00
raise osv . except_osv ( _ ( ' Warning! ' ) , _ ( " Something went wrong with the configuration of attachments with google drive.Please contact your Administrator to fix the problem. " ) )
2013-03-08 13:30:39 +00:00
model = self . pool . get ( action_filter . model_id )
domain = [ ( ' id ' , ' in ' , [ record_ids ] ) ] + eval ( action_filter . domain )
ctx = dict ( context or { } )
ctx . update ( eval ( action_filter . context ) )
record_ids = model . search ( cr , uid , domain , context = ctx )
return record_ids
2013-04-01 08:03:23 +00:00
def _list_all_models ( self , cr , uid , context = None ) :
2013-04-01 09:31:52 +00:00
cr . execute ( " SELECT model, name from ir_model order by name " )
2013-04-01 08:03:23 +00:00
return cr . fetchall ( )
2013-03-05 13:17:57 +00:00
def _resource_get ( self , cr , uid , ids , name , arg , context = None ) :
result = { }
for data in self . browse ( cr , uid , ids , context ) :
template_url = data . gdocs_template_url
2013-03-20 05:39:10 +00:00
try :
url = urlparse ( template_url )
res = url . path . split ( ' / ' )
resource = res [ 1 ]
2013-05-10 06:35:01 +00:00
if res [ 1 ] == " spreadsheet " :
2013-03-20 05:39:10 +00:00
key = url . query . split ( ' = ' ) [ 1 ]
else :
key = res [ 3 ]
2013-05-09 14:10:01 +00:00
result [ data . id ] = str ( key )
2013-03-20 05:39:10 +00:00
except :
raise osv . except_osv ( _ ( ' Incorrect URL! ' ) , _ ( " Please enter a valid URL. " ) )
2013-03-05 13:17:57 +00:00
return result
2013-05-09 14:10:01 +00:00
def _client_id_get ( self , cr , uid , ids , name , arg , context = None ) :
result = { }
for config_id in ids :
2013-05-22 10:28:57 +00:00
config = self . pool [ ' ir.config_parameter ' ]
2013-06-25 10:58:19 +00:00
result [ config_id ] = config . get_param ( cr , SUPERUSER_ID , ' google_docs_client_id ' )
2013-05-09 14:10:01 +00:00
return result
2012-02-29 18:45:20 +00:00
_columns = {
2013-03-22 12:28:59 +00:00
' name ' : fields . char ( ' Template Name ' , required = True , size = 1024 ) ,
2013-04-01 08:03:23 +00:00
' model_id ' : fields . selection ( _list_all_models , ' Model ' , required = True ) ,
2013-02-28 07:28:22 +00:00
' filter_id ' : fields . many2one ( ' ir.filters ' , ' Filter ' ) ,
2013-03-19 13:28:27 +00:00
' gdocs_template_url ' : fields . char ( ' Template URL ' , required = True , size = 1024 ) ,
2013-05-10 06:35:01 +00:00
' gdocs_resource_id ' : fields . function ( _resource_get , type = " char " , string = ' Resource Id ' ) ,
2013-06-25 10:58:19 +00:00
' google_docs_client_id ' : fields . function ( _client_id_get , type = " char " , string = ' Google Client ' ) ,
2013-04-01 08:03:23 +00:00
' name_template ' : fields . char ( ' Google Drive Name Pattern ' , size = 64 , help = ' Choose how the new google drive will be named, on google side. Eg. gdoc_ %(field_name)s ' , required = True ) ,
2013-05-09 14:10:01 +00:00
}
2012-02-29 18:45:20 +00:00
2013-03-22 12:28:59 +00:00
def onchange_model_id ( self , cr , uid , ids , model_id , context = None ) :
2013-04-04 07:05:23 +00:00
res = { ' domain ' : { ' filter_id ' : [ ] } }
2013-03-12 09:32:39 +00:00
if model_id :
2013-04-04 07:05:23 +00:00
res [ ' domain ' ] = { ' filter_id ' : [ ( ' model_id ' , ' = ' , model_id ) ] }
2013-03-12 09:32:39 +00:00
else :
2013-04-04 07:05:23 +00:00
res [ ' value ' ] = { ' filter_id ' : False }
2013-03-12 09:32:39 +00:00
return res
2013-03-04 05:20:58 +00:00
2012-02-29 18:45:20 +00:00
_defaults = {
2013-04-01 08:03:23 +00:00
' name_template ' : ' %(name)s _ %(model)s _ %(filter)s _gdrive ' ,
2012-02-29 18:45:20 +00:00
}
2013-05-10 06:35:01 +00:00
2013-03-22 12:28:59 +00:00
def _check_model_id ( self , cr , uid , ids , context = None ) :
2013-03-28 07:12:12 +00:00
config_id = self . browse ( cr , uid , ids [ 0 ] , context = context )
2013-04-01 08:03:23 +00:00
if config_id . filter_id . id and config_id . model_id != config_id . filter_id . model_id :
2013-03-28 07:12:12 +00:00
return False
2013-03-22 12:28:59 +00:00
return True
_constraints = [
2013-05-10 06:35:01 +00:00
( _check_model_id , ' Model of selected filter is not matching with model of current template. ' , [ ' model_id ' , ' filter_id ' ] ) ,
2013-03-22 12:28:59 +00:00
]
2012-03-28 08:29:48 +00:00
config ( )
2013-05-23 10:41:55 +00:00
2013-06-25 10:58:19 +00:00
2013-05-23 13:38:48 +00:00
class base_config_settings ( osv . osv ) :
_inherit = " base.config.settings "
2013-05-23 10:41:55 +00:00
_columns = {
2013-06-25 10:58:19 +00:00
' google_docs_authorization_code ' : fields . char ( ' Paste Generated " Authorization Code " from google to here ' , size = 124 ) ,
}