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
from openerp . osv import fields , osv
from openerp . tools . translate import _
2012-12-09 18:22:37 +00:00
_logger = logging . getLogger ( __name__ )
2012-03-02 10:35:05 +00:00
try :
import gdata . docs . data
import gdata . docs . client
2013-02-01 11:51:53 +00:00
# API breakage madness in the gdata API - those guys are insane.
try :
# gdata 2.0.15+
gdata . docs . client . DocsClient . copy_resource
except AttributeError :
# gdata 2.0.14- : copy_resource() was copy()
gdata . docs . client . DocsClient . copy_resource = gdata . docs . client . DocsClient . copy
try :
# gdata 2.0.16+
gdata . docs . client . DocsClient . get_resource_by_id
except AttributeError :
try :
# gdata 2.0.15+
gdata . docs . client . DocsClient . get_resource_by_self_link
def get_resource_by_id_2_0_16 ( self , resource_id , * * kwargs ) :
return self . GetResourceBySelfLink (
gdata . docs . client . RESOURCE_FEED_URI + ( ' / %s ' % resource_id ) , * * kwargs )
gdata . docs . client . DocsClient . get_resource_by_id = get_resource_by_id_2_0_16
except AttributeError :
# gdata 2.0.14- : alias get_resource_by_id()
gdata . docs . client . DocsClient . get_resource_by_id = gdata . docs . client . DocsClient . get_doc
try :
import atom . http_interface
_logger . info ( ' GData lib version ` %s ` detected ' % atom . http_interface . USER_AGENT )
except ( ImportError , AttributeError ) :
_logger . debug ( ' GData lib version could not be detected ' , exc_info = True )
2012-03-02 10:35:05 +00:00
except ImportError :
2012-10-10 20:47:33 +00:00
_logger . warning ( " Please install latest gdata-python-client from http://code.google.com/p/gdata-python-client/downloads/list " )
2012-02-24 10:52:15 +00:00
2013-02-01 11:51:53 +00:00
2012-02-29 18:45:20 +00:00
class google_docs_ir_attachment ( osv . osv ) :
2012-02-29 12:29:40 +00:00
_inherit = ' ir.attachment '
2012-02-24 10:52:15 +00:00
2012-05-23 09:51:36 +00:00
def _auth ( self , cr , uid , context = None ) :
2012-03-28 08:29:48 +00:00
'''
Connexion with google base account
@return client object for connexion
'''
#pool the google.login in google_base_account
google_pool = self . pool . get ( ' google.login ' )
2012-05-23 09:51:36 +00:00
#get gmail password and login. We use default_get() instead of a create() followed by a read() on the
# google.login object, because it is easier. The keys 'user' and 'password' ahve to be passed in the dict
# but the values will be replaced by the user gmail password and login.
2013-02-01 11:51:53 +00:00
user_config = google_pool . default_get ( cr , uid , { ' user ' : ' ' , ' password ' : ' ' } , context = context )
2012-03-28 08:29:48 +00:00
#login gmail account
2013-02-01 11:51:53 +00:00
client = google_pool . google_login ( user_config [ ' user ' ] , user_config [ ' password ' ] , type = ' docs_client ' , context = context )
2012-03-28 09:47:18 +00:00
if not client :
2013-02-01 11:51:53 +00:00
raise osv . except_osv ( _ ( ' Google Docs Error! ' ) , _ ( " Check your google configuration in Users/Users/Synchronization tab. " ) )
_logger . info ( ' Logged into google docs as %s ' , user_config [ ' user ' ] )
2012-02-29 18:45:20 +00:00
return client
2012-02-24 10:52:15 +00:00
2012-05-23 09:51:36 +00:00
def create_empty_google_doc ( self , cr , uid , res_model , res_id , context = None ) :
''' Create a new google document, empty and with a default type (txt)
: param res_model : the object for which the google doc is created
: param res_id : the Id of the object for which the google doc is created
: return : the ID of the google document object created
2012-02-24 14:01:19 +00:00
'''
2012-03-28 08:29:48 +00:00
#login with the base account google module
2012-05-23 09:51:36 +00:00
client = self . _auth ( cr , uid , context = context )
2012-03-01 14:45:07 +00:00
# create the document in google docs
2012-11-01 07:26:31 +00:00
title = " %s %s " % ( context . get ( " name " , " Untitled Document. " ) , datetime . today ( ) . strftime ( DEFAULT_SERVER_DATETIME_FORMAT ) )
2012-10-23 12:58:04 +00:00
local_resource = gdata . docs . data . Resource ( gdata . docs . data . DOCUMENT_LABEL , title = title )
2012-03-28 08:29:48 +00:00
#create a new doc in Google Docs
gdocs_resource = client . post ( entry = local_resource , uri = ' https://docs.google.com/feeds/default/private/full/ ' )
2012-05-23 09:51:36 +00:00
# create an ir.attachment into the db
2012-03-01 14:45:07 +00:00
self . create ( cr , uid , {
2012-05-23 09:51:36 +00:00
' res_model ' : res_model ,
' res_id ' : res_id ,
2012-03-01 14:45:07 +00:00
' type ' : ' url ' ,
2012-11-01 07:18:46 +00:00
' name ' : title ,
2012-03-28 08:29:48 +00:00
' url ' : gdocs_resource . get_alternate_link ( ) . href ,
2012-05-23 09:51:36 +00:00
} , context = context )
2012-11-01 07:18:46 +00:00
return { ' resource_id ' : gdocs_resource . resource_id . text ,
' title ' : title ,
' url ' : gdocs_resource . get_alternate_link ( ) . href }
2012-02-24 10:52:15 +00:00
2012-05-23 09:51:36 +00:00
def copy_gdoc ( self , cr , uid , res_model , res_id , name_gdocs , gdoc_template_id , context = None ) :
2012-03-28 11:41:13 +00:00
'''
copy an existing document in google docs
2012-05-23 09:51:36 +00:00
: param res_model : the object for which the google doc is created
: param res_id : the Id of the object for which the google doc is created
: param name_gdocs : the name of the future ir . attachment that will be created . Based on the google doc template foun .
: param gdoc_template_id : the id of the google doc document to copy
: return : the ID of the google document object created
2012-03-28 11:41:13 +00:00
'''
2012-05-23 09:51:36 +00:00
#login with the base account google module
2012-03-28 08:29:48 +00:00
client = self . _auth ( cr , uid )
2012-02-29 18:45:20 +00:00
# fetch and copy the original document
2012-03-28 11:41:13 +00:00
try :
2013-02-01 11:51:53 +00:00
doc = client . get_resource_by_id ( gdoc_template_id )
2012-03-28 11:41:13 +00:00
#copy the document you choose in the configuration
2013-02-01 11:51:53 +00:00
copy_resource = client . copy_resource ( doc , name_gdocs )
2012-03-28 11:41:13 +00:00
except :
2013-02-25 09:16:39 +00:00
raise osv . except_osv ( _ ( ' Google Drive Error! ' ) , _ ( " Your resource id is not correct. You can find the id in the google docs URL. " ) )
2012-05-23 09:51:36 +00:00
# create an ir.attachment
2012-03-01 14:45:07 +00:00
self . create ( cr , uid , {
2012-05-23 09:51:36 +00:00
' res_model ' : res_model ,
' res_id ' : res_id ,
2012-03-01 14:45:07 +00:00
' type ' : ' url ' ,
2012-03-30 14:51:49 +00:00
' name ' : name_gdocs ,
2012-03-01 14:45:07 +00:00
' url ' : copy_resource . get_alternate_link ( ) . href
2012-05-23 09:51:36 +00:00
} , context = context )
return copy_resource . resource_id . text
2012-02-29 18:45:20 +00:00
2012-05-23 09:51:36 +00:00
def google_doc_get ( self , cr , uid , res_model , ids , context = None ) :
'''
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 )
: return : the google document object created
'''
2012-10-19 10:40:20 +00:00
if len ( ids ) != 1 :
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. " ) )
2012-05-23 09:51:36 +00:00
res_id = ids [ 0 ]
pool_ir_attachment = self . pool . get ( ' ir.attachment ' )
2012-03-30 14:51:49 +00:00
pool_gdoc_config = self . pool . get ( ' google.docs.config ' )
2012-05-23 09:51:36 +00:00
name_gdocs = ' '
model_fields_dic = self . pool . get ( res_model ) . read ( cr , uid , res_id , [ ] , context = context )
# check if a model is configured with a template
google_docs_config = pool_gdoc_config . search ( cr , uid , [ ( ' model_id ' , ' = ' , res_model ) ] , context = context )
2012-03-19 10:31:32 +00:00
if google_docs_config :
2012-05-23 09:51:36 +00:00
name_gdocs = pool_gdoc_config . browse ( cr , uid , google_docs_config , context = context ) [ 0 ] . name_template
2012-10-17 06:46:15 +00:00
try :
name_gdocs = name_gdocs % model_fields_dic
except :
2013-02-25 09:16:39 +00:00
raise osv . except_osv ( _ ( ' Key Error! ' ) , _ ( " Your Google Drive Name Pattern ' s key does not found in object. " ) )
2012-05-23 09:51:36 +00:00
google_template_id = pool_gdoc_config . browse ( cr , uid , google_docs_config [ 0 ] , context = context ) . gdocs_resource_id
google_document = pool_ir_attachment . copy_gdoc ( cr , uid , res_model , res_id , name_gdocs , google_template_id , context = context )
2012-03-19 10:31:32 +00:00
else :
2012-05-23 09:51:36 +00:00
google_document = pool_ir_attachment . create_empty_google_doc ( cr , uid , res_model , res_id , context = context )
return google_document
2012-03-05 16:11:15 +00:00
2012-03-12 14:41:31 +00:00
class config ( osv . osv ) :
_name = ' google.docs.config '
2013-02-25 09:16:39 +00:00
_description = " Google Drive templates config "
2012-02-29 18:45:20 +00:00
_columns = {
2012-09-26 14:08:02 +00:00
' model_id ' : fields . many2one ( ' ir.model ' , ' Model ' , required = True ) ,
2012-10-15 07:14:27 +00:00
' gdocs_resource_id ' : fields . char ( ' Google Resource ID to Use as Template ' , size = 64 , help = '''
2012-05-23 11:02:15 +00:00
This is the id of the template document , on google side . You can find it thanks to its URL :
2012-05-23 09:51:36 +00:00
* for a text document with url like ` https : / / docs . google . com / a / openerp . com / document / d / 123456789 / edit ` , the ID is ` document : 123456789 `
* for a spreadsheet document with url like ` https : / / docs . google . com / a / openerp . com / spreadsheet / ccc ? key = 123456789 #gid=0`, the ID is `spreadsheet:123456789`
* for a presentation ( slide show ) document with url like ` https : / / docs . google . com / a / openerp . com / presentation / d / 123456789 / edit #slide=id.p`, the ID is `presentation:123456789`
* for a drawing document with url like ` https : / / docs . google . com / a / openerp . com / drawings / d / 123456789 / edit ` , the ID is ` drawings : 123456789 `
. . .
2012-10-23 12:58:04 +00:00
''' , required=True),
2013-02-25 09:16:39 +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 ) ,
2012-02-29 18:45:20 +00:00
}
_defaults = {
2012-05-23 09:51:36 +00:00
' name_template ' : ' gdoc_ %(name)s ' ,
2012-02-29 18:45:20 +00:00
}
2012-03-28 08:29:48 +00:00
config ( )