[MERGE] forward port of branch saas-9 up to da8a312
This commit is contained in:
@@ -7,34 +7,105 @@ from StringIO import StringIO
|
|||||||
|
|
||||||
import pyPdf
|
import pyPdf
|
||||||
|
|
||||||
import openerp
|
from openerp.osv import osv
|
||||||
from openerp.osv import fields, osv
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
FTYPES = ['docx', 'pptx', 'xlsx', 'opendoc', 'pdf']
|
||||||
|
|
||||||
|
# Keep function in case it is necessary to do toUnicode(buf.encode('ascii', 'replace'))
|
||||||
|
def toUnicode(s):
|
||||||
|
try:
|
||||||
|
return s.decode('utf-8')
|
||||||
|
except UnicodeError:
|
||||||
|
try:
|
||||||
|
return s.decode('latin')
|
||||||
|
except UnicodeError:
|
||||||
|
try:
|
||||||
|
return s.encode('ascii')
|
||||||
|
except UnicodeError:
|
||||||
|
return s
|
||||||
|
|
||||||
|
def textToString(element):
|
||||||
|
buff = u""
|
||||||
|
for node in element.childNodes:
|
||||||
|
if node.nodeType == xml.dom.Node.TEXT_NODE:
|
||||||
|
buff += node.nodeValue
|
||||||
|
elif node.nodeType == xml.dom.Node.ELEMENT_NODE:
|
||||||
|
buff += textToString(node)
|
||||||
|
return buff
|
||||||
|
|
||||||
|
|
||||||
class IrAttachment(osv.osv):
|
class IrAttachment(osv.osv):
|
||||||
_inherit = 'ir.attachment'
|
_inherit = 'ir.attachment'
|
||||||
|
|
||||||
def _index_odt(self, bin_data):
|
def _index_docx(self, bin_data):
|
||||||
|
'''Index Microsoft .docx documents'''
|
||||||
buf = u""
|
buf = u""
|
||||||
f = StringIO(bin_data)
|
f = StringIO(bin_data)
|
||||||
if zipfile.is_zipfile(f):
|
if zipfile.is_zipfile(f):
|
||||||
try:
|
try:
|
||||||
zf = zipfile.ZipFile(f)
|
zf = zipfile.ZipFile(f)
|
||||||
self.content = xml.dom.minidom.parseString(zf.read("content.xml"))
|
content = xml.dom.minidom.parseString(zf.read("word/document.xml"))
|
||||||
|
for val in ["w:p", "w:h", "text:list"]:
|
||||||
|
for element in content.getElementsByTagName(val):
|
||||||
|
buf += textToString(element) + "\n"
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return buf
|
||||||
|
|
||||||
|
def _index_pptx(self, bin_data):
|
||||||
|
'''Index Microsoft .pptx documents'''
|
||||||
|
|
||||||
|
buf = u""
|
||||||
|
f = StringIO(bin_data)
|
||||||
|
if zipfile.is_zipfile(f):
|
||||||
|
try:
|
||||||
|
zf = zipfile.ZipFile(f)
|
||||||
|
zf_filelist = [x for x in zf.namelist() if x.startswith('ppt/slides/slide')]
|
||||||
|
for i in range(1, len(zf_filelist) + 1):
|
||||||
|
content = xml.dom.minidom.parseString(zf.read('ppt/slides/slide%s.xml' % i))
|
||||||
|
for val in ["a:t"]:
|
||||||
|
for element in content.getElementsByTagName(val):
|
||||||
|
buf += textToString(element) + "\n"
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return buf
|
||||||
|
|
||||||
|
def _index_xlsx(self, bin_data):
|
||||||
|
'''Index Microsoft .xlsx documents'''
|
||||||
|
|
||||||
|
buf = u""
|
||||||
|
f = StringIO(bin_data)
|
||||||
|
if zipfile.is_zipfile(f):
|
||||||
|
try:
|
||||||
|
zf = zipfile.ZipFile(f)
|
||||||
|
content = xml.dom.minidom.parseString(zf.read("xl/sharedStrings.xml"))
|
||||||
|
for val in ["t"]:
|
||||||
|
for element in content.getElementsByTagName(val):
|
||||||
|
buf += textToString(element) + "\n"
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return buf
|
||||||
|
|
||||||
|
def _index_opendoc(self, bin_data):
|
||||||
|
'''Index OpenDocument documents (.odt, .ods...)'''
|
||||||
|
|
||||||
|
buf = u""
|
||||||
|
f = StringIO(bin_data)
|
||||||
|
if zipfile.is_zipfile(f):
|
||||||
|
try:
|
||||||
|
zf = zipfile.ZipFile(f)
|
||||||
|
content = xml.dom.minidom.parseString(zf.read("content.xml"))
|
||||||
for val in ["text:p", "text:h", "text:list"]:
|
for val in ["text:p", "text:h", "text:list"]:
|
||||||
for element in self.content.getElementsByTagName(val) :
|
for element in content.getElementsByTagName(val):
|
||||||
for node in element.childNodes :
|
buf += textToString(element) + "\n"
|
||||||
if node.nodeType == xml.dom.Node.TEXT_NODE :
|
|
||||||
buf += node.nodeValue
|
|
||||||
elif node.nodeType == xml.dom.Node.ELEMENT_NODE :
|
|
||||||
buf += self.textToString(node)
|
|
||||||
buf += "\n"
|
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return buf
|
return buf
|
||||||
|
|
||||||
def _index_pdf(self, bin_data):
|
def _index_pdf(self, bin_data):
|
||||||
|
'''Index PDF documents'''
|
||||||
|
|
||||||
buf = u""
|
buf = u""
|
||||||
if bin_data.startswith('%PDF-'):
|
if bin_data.startswith('%PDF-'):
|
||||||
f = StringIO(bin_data)
|
f = StringIO(bin_data)
|
||||||
@@ -47,14 +118,9 @@ class IrAttachment(osv.osv):
|
|||||||
return buf
|
return buf
|
||||||
|
|
||||||
def _index(self, cr, uid, bin_data, datas_fname, mimetype):
|
def _index(self, cr, uid, bin_data, datas_fname, mimetype):
|
||||||
# try to index odt content
|
for ftype in FTYPES:
|
||||||
buf = self._index_odt(bin_data)
|
buf = getattr(self, '_index_%s' % ftype)(bin_data)
|
||||||
if buf:
|
if buf:
|
||||||
return buf
|
return buf
|
||||||
# try to index pdf content
|
|
||||||
buf = self._index_pdf(bin_data)
|
|
||||||
if buf:
|
|
||||||
return buf
|
|
||||||
|
|
||||||
return super(IrAttachment, self)._index(cr, uid, bin_data, datas_fname, mimetype)
|
return super(IrAttachment, self)._index(cr, uid, bin_data, datas_fname, mimetype)
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ var KanbanColumn = Widget.extend({
|
|||||||
connectWith: '.o_kanban_group',
|
connectWith: '.o_kanban_group',
|
||||||
revert: 0,
|
revert: 0,
|
||||||
delay: 0,
|
delay: 0,
|
||||||
items: '> .o_kanban_record',
|
items: '> .o_kanban_record:not(.o_updating)',
|
||||||
helper: 'clone',
|
helper: 'clone',
|
||||||
cursor: 'move',
|
cursor: 'move',
|
||||||
over: function () {
|
over: function () {
|
||||||
@@ -117,6 +117,7 @@ var KanbanColumn = Widget.extend({
|
|||||||
// adding record to this column
|
// adding record to this column
|
||||||
self.records.push(record);
|
self.records.push(record);
|
||||||
record.setParent(self);
|
record.setParent(self);
|
||||||
|
ui.item.addClass('o_updating');
|
||||||
self.trigger_up('kanban_column_add_record', {record: record});
|
self.trigger_up('kanban_column_add_record', {record: record});
|
||||||
}
|
}
|
||||||
self.update_column();
|
self.update_column();
|
||||||
|
|||||||
@@ -99,12 +99,19 @@ animation.registry.parallax = animation.Class.extend({
|
|||||||
animation.registry.share = animation.Class.extend({
|
animation.registry.share = animation.Class.extend({
|
||||||
selector: ".oe_share",
|
selector: ".oe_share",
|
||||||
start: function () {
|
start: function () {
|
||||||
|
var url_regex = /(\?(?:|.*&)(?:u|url|body)=)(.*?)(&|#|$)/;
|
||||||
|
var title_regex = /(\?(?:|.*&)(?:title|text|subject)=)(.*?)(&|#|$)/;
|
||||||
var url = encodeURIComponent(window.location.href);
|
var url = encodeURIComponent(window.location.href);
|
||||||
var title = encodeURIComponent($("title").text());
|
var title = encodeURIComponent($("title").text());
|
||||||
this.$("a").each(function () {
|
this.$("a").each(function () {
|
||||||
var $a = $(this);
|
var $a = $(this);
|
||||||
var url_regex = /\{url\}|%7Burl%7D/, title_regex = /\{title\}|%7Btitle%7D/;
|
$a.attr("href", function(i, href) {
|
||||||
$a.attr("href", $(this).attr("href").replace(url_regex, url).replace(title_regex, title));
|
return href.replace(url_regex, function (match, a, b, c) {
|
||||||
|
return a + url + c;
|
||||||
|
}).replace(title_regex, function (match, a, b, c) {
|
||||||
|
return a + title + c;
|
||||||
|
});
|
||||||
|
});
|
||||||
if ($a.attr("target") && $a.attr("target").match(/_blank/i) && !$a.closest('.o_editable').length) {
|
if ($a.attr("target") && $a.attr("target").match(/_blank/i) && !$a.closest('.o_editable').length) {
|
||||||
$a.on('click', function () {
|
$a.on('click', function () {
|
||||||
window.open(this.href,'','menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=550,width=600');
|
window.open(this.href,'','menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=550,width=600');
|
||||||
|
|||||||
+1
-1
@@ -1031,7 +1031,7 @@ class Field(object):
|
|||||||
target = records - computed
|
target = records - computed
|
||||||
elif path and env.in_onchange:
|
elif path and env.in_onchange:
|
||||||
target = (target.browse(env.cache[field]) - computed).filtered(
|
target = (target.browse(env.cache[field]) - computed).filtered(
|
||||||
lambda rec: rec._mapped_cache(path) & records
|
lambda rec: rec if path == 'id' else rec._mapped_cache(path) & records
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
target = target.browse(env.cache[field]) - computed
|
target = target.browse(env.cache[field]) - computed
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ requires =
|
|||||||
python-requests
|
python-requests
|
||||||
python-vobject
|
python-vobject
|
||||||
python-werkzeug
|
python-werkzeug
|
||||||
|
python-xlwt
|
||||||
python-yaml
|
python-yaml
|
||||||
pytz
|
pytz
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ RUN yum install -d 0 -e 0 epel-release -y && \
|
|||||||
python-requests \
|
python-requests \
|
||||||
python-vobject \
|
python-vobject \
|
||||||
python-werkzeug \
|
python-werkzeug \
|
||||||
|
python-xlwt \
|
||||||
python-yaml \
|
python-yaml \
|
||||||
pytz \
|
pytz \
|
||||||
postgresql \
|
postgresql \
|
||||||
|
|||||||
Reference in New Issue
Block a user