[IMP] missing picture
[odoo/odoo.git] / addons / google_spreadsheet / google_spreadsheet.py
1 ##############################################################################
2 #
3 #    OpenERP, Open Source Management Solution
4 #    Copyright (C) 2004-2012 OpenERP SA (<http://www.openerp.com>).
5 #
6 #    This program is free software: you can redistribute it and/or modify
7 #    it under the terms of the GNU Affero General Public License as
8 #    published by the Free Software Foundation, either version 3 of the
9 #    License, or (at your option) any later version.
10 #
11 #    This program is distributed in the hope that it will be useful,
12 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 #    GNU Affero General Public License for more details.
15 #
16 #    You should have received a copy of the GNU Affero General Public License
17 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 #
19 ##############################################################################
20
21 import cgi
22 import simplejson
23 import logging
24 from lxml import etree
25 import re
26 import werkzeug.urls
27 import urllib2
28
29 from openerp.osv import osv
30 from openerp import SUPERUSER_ID
31
32 _logger = logging.getLogger(__name__)
33
34 class config(osv.osv):
35     _inherit = 'google.drive.config'
36
37     def get_google_scope(self):
38         scope = super(config, self).get_google_scope()
39         return '%s https://spreadsheets.google.com/feeds' % scope
40
41     def write_config_formula(self, cr, uid, attachment_id, spreadsheet_key, model, domain, groupbys, view_id, context=None):
42         access_token = self.get_access_token(cr, uid, scope='https://spreadsheets.google.com/feeds', context=context)
43
44         fields = self.pool.get(model).fields_view_get(cr, uid, view_id=view_id, view_type='tree')
45         doc = etree.XML(fields.get('arch'))
46         display_fields = []
47         for node in doc.xpath("//field"):
48             if node.get('modifiers'):
49                 modifiers = simplejson.loads(node.get('modifiers'))
50                 if not modifiers.get('invisible') and not modifiers.get('tree_invisible'):
51                     display_fields.append(node.get('name'))
52         fields = " ".join(display_fields)
53         domain = domain.replace("'", r"\'").replace('"', "'")
54         if groupbys:
55             fields = "%s %s" % (groupbys, fields)
56             formula = '=oe_read_group("%s";"%s";"%s";"%s")' % (model, fields, groupbys, domain)
57         else:
58             formula = '=oe_browse("%s";"%s";"%s")' % (model, fields, domain)
59         url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url')
60         dbname = cr.dbname
61         user = self.pool['res.users'].read(cr, uid, uid, ['login', 'password'], context=context)
62         username = user['login']
63         password = user['password']
64         if not password:
65             config_formula = '=oe_settings("%s";"%s")' % (url, dbname)
66         else:
67             config_formula = '=oe_settings("%s";"%s";"%s";"%s")' % (url, dbname, username, password)
68         request = '''<feed xmlns="http://www.w3.org/2005/Atom"
69       xmlns:batch="http://schemas.google.com/gdata/batch"
70       xmlns:gs="http://schemas.google.com/spreadsheets/2006">
71   <id>https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full</id>
72   <entry>
73     <batch:id>A1</batch:id>
74     <batch:operation type="update"/>
75     <id>https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full/R1C1</id>
76     <link rel="edit" type="application/atom+xml"
77       href="https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full/R1C1"/>
78     <gs:cell row="1" col="1" inputValue="{formula}"/>
79   </entry>
80   <entry>
81     <batch:id>A2</batch:id>
82     <batch:operation type="update"/>
83     <id>https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full/R60C15</id>
84     <link rel="edit" type="application/atom+xml"
85       href="https://spreadsheets.google.com/feeds/cells/{key}/od6/private/full/R60C15"/>
86     <gs:cell row="60" col="15" inputValue="{config}"/>
87   </entry>
88 </feed>''' .format(key=spreadsheet_key, formula=cgi.escape(formula, quote=True), config=cgi.escape(config_formula, quote=True))
89
90         try:
91             req = urllib2.Request(
92                 'https://spreadsheets.google.com/feeds/cells/%s/od6/private/full/batch?%s' % (spreadsheet_key, werkzeug.url_encode({'v': 3, 'access_token': access_token})),
93                 data=request,
94                 headers={'content-type': 'application/atom+xml', 'If-Match': '*'})
95             urllib2.urlopen(req)
96         except (urllib2.HTTPError, urllib2.URLError):
97             _logger.warning("An error occured while writting the formula on the Google Spreadsheet.")
98
99         description = '''
100         formula: %s
101         ''' % formula
102         if attachment_id:
103             self.pool['ir.attachment'].write(cr, uid, attachment_id, {'description': description}, context=context)
104         return True
105
106     def set_spreadsheet(self, cr, uid, model, domain, groupbys, view_id, context=None):
107         try:
108             config_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'google_spreadsheet', 'google_spreadsheet_template')[1]
109         except ValueError:
110             raise
111         config = self.browse(cr, uid, config_id, context=context)
112         title = 'Spreadsheet %s' % model
113         res = self.copy_doc(cr, uid, False, config.google_drive_resource_id, title, model, context=context)
114
115         mo = re.search("(key=|/d/)([A-Za-z0-9-_]+)", res['url'])
116         if mo:
117             key = mo.group(2)
118
119         self.write_config_formula(cr, uid, res.get('id'), key, model, domain, groupbys, view_id, context=context)
120         return res