[IMP] font: better handeling of multiworker environement

bzr revid: mat@openerp.com-20131209151454-5rylu5alldd3ixmh
This commit is contained in:
Martin Trigaux 2013-12-09 16:14:54 +01:00
parent 5f1f44401f
commit aac5c9d6eb
5 changed files with 60 additions and 53 deletions

View File

@ -91,5 +91,25 @@ Administrator</field>
<field eval="10" name="sequence"/>
</record>
<!-- Basic fonts family included in PDF standart, will always be in the font list -->
<record model="res.font" id="base.font_helvetica">
<field name="name">Helvetica</field>
<field name="familly">Helvetica</field>
<field name="path">/dev/null</field>
<field name="mode">all</field>
</record>
<record model="res.font" id="base.font_times">
<field name="name">Times</field>
<field name="familly">Times</field>
<field name="path">/dev/null</field>
<field name="mode">all</field>
</record>
<record model="res.font" id="base.font_courier">
<field name="name">Courier</field>
<field name="familly">Courier</field>
<field name="path">/dev/null</field>
<field name="mode">all</field>
</record>
</data>
</openerp>

View File

@ -297,12 +297,7 @@ class res_company(osv.osv):
def _get_font(self, cr, uid, ids):
font_obj = self.pool.get('res.font')
res = font_obj.search(cr, uid, [('family', '=', 'Helvetica'), ('mode', '=', 'all')], limit=1)
if res:
return res[0]
# not even the basic pdf fonts, initiate the db
font_obj._base_populate_font(cr, uid)
res = font_obj.search(cr, uid, [('family', '=', 'Helvetica'), ('mode', '=', 'all')], limit=1)
return res and res[0] or False
return res and res[0] or False
_header = """
<header>

View File

@ -40,7 +40,7 @@ _logger = logging.getLogger(__name__)
class res_font(osv.Model):
_name = "res.font"
_description = 'Fonts available'
_order = 'name,family,id'
_order = 'family,name,id'
_rec_name = 'family'
_columns = {
@ -54,65 +54,61 @@ class res_font(osv.Model):
('name_font_uniq', 'unique(family, name)', 'You can not register two fonts with the same name'),
]
def _base_populate_font(self, cr, uid, context=None):
if not self.search(cr, uid, [('path', '=', '/dev/null')], context=context):
# populate db with basic pdf fonts
for family, name, path, mode in customfonts.BasePDFFonts:
self.create(cr, uid, {
'family': family, 'name': name,
'path': path, 'mode': mode,
}, context=context)
return True
def font_scan(self, cr, uid, lazy=False, context=None):
"""Action of loading fonts
In lazy mode will scan the filesystem only if there is no founts in the database and sync if no font in CustomTTFonts
In not lazy mode will force scan filesystem and sync
"""
if lazy:
# lazy loading, scan only if no fonts in db
found_fonts_ids = self.search(cr, uid, [('path', '!=', '/dev/null')], context=context)
if not found_fonts_ids:
# no scan yet or no font found on the system, scan the filesystem
self._discover_fonts(cr, uid, context=context)
self._register_fonts(cr, uid, context=context)
else:
if len(customfonts.CustomTTFonts) == 0:
# CustomTTFonts list is empty
for font in self.browse(cr, uid, found_fonts_ids, context=context):
customfonts.CustomTTFonts.append((font.family, font.name, font.path, font.mode))
self._scan_disk(cr, uid, context=context)
elif len(customfonts.CustomTTFonts) == 0:
# CustomTTFonts list is empty
self._sync(cr, uid, context=context)
else:
self._discover_fonts(cr, uid, context=context)
self._register_fonts(cr, uid, context=context)
self._scan_disk(cr, uid, context=context)
return True
def _discover_fonts(self, cr, uid, context=None):
"""Scan fonts on the file system, add them to the list of known fonts
and create font object for the new ones"""
customfonts.CustomTTFonts = []
found_fonts = {}
def _scan_disk(self, cr, uid, context=None):
"""Scan the file system and register the result in database"""
found_fonts = []
for font_path in customfonts.list_all_sysfonts():
try:
font = ttfonts.TTFontFile(font_path)
_logger.debug("Found font %s at %s", font.name, font_path)
if not found_fonts.get(font.familyName):
found_fonts[font.familyName] = {'name': font.familyName}
mode = font.styleName.lower().replace(" ", "")
customfonts.CustomTTFonts.append((font.familyName, font.name, font_path, mode))
found_fonts.append((font.familyName, font.name, font_path, font.styleName))
except ttfonts.TTFError:
_logger.warning("Could not register Font %s", font_path)
def _register_fonts(self, cr, uid, context=None):
# add new custom fonts
for family, name, path, mode in customfonts.CustomTTFonts:
for family, name, path, mode in found_fonts:
if not self.search(cr, uid, [('family', '=', family), ('name', '=', name)], context=context):
self.create(cr, uid, {
'family': family, 'name': name,
'path': path, 'mode': mode,
}, context=context)
# remove fonts not present on disk
existing_font_names = [name for (family, name, path, mode) in customfonts.CustomTTFonts]
# remove fonts not present on the disk anymore
existing_font_names = [name for (family, name, path, mode) in found_fonts]
inexistant_fonts = self.search(cr, uid, [('name', 'not in', existing_font_names), ('path', '!=', '/dev/null')], context=context)
if inexistant_fonts:
return self.unlink(cr, uid, inexistant_fonts, context=context)
self.unlink(cr, uid, inexistant_fonts, context=context)
self.clear_caches()
self._sync(cr, uid, context=context)
return True
def _sync(self, cr, uid, context=None):
"""Set the customfonts.CustomTTFonts list to the content of the database"""
customfonts.CustomTTFonts = []
found_fonts_ids = self.search(cr, uid, [('path', '!=', '/dev/null')], context=context)
for font in self.browse(cr, uid, found_fonts_ids, context=None):
customfonts.CustomTTFonts.append((font.family, font.name, font.path, font.mode))
return True
def clear_caches(self):
"""Force worker to resync at next report loading by setting an empty font list"""
customfonts.CustomTTFonts = []
return super(res_font, self).clear_caches()

View File

@ -38,13 +38,6 @@ and Ubuntu distros, we have to override the search path, too.
"""
_logger = logging.getLogger(__name__)
# Basic fonts family included in PDF standart, will always be in the font list
BasePDFFonts = [
('Helvetica', 'Helvetica', '/dev/null', 'all'),
('Times', 'Times', '/dev/null', 'all'),
('Courier', 'Courier', '/dev/null', 'all'),
]
CustomTTFonts = []
# Search path for TTF files, in addition of rl_config.TTFSearchPath

View File

@ -56,8 +56,11 @@ def select_fontname(fontname, default_fontname):
try:
pdfmetrics.getFont(fontname)
except Exception:
_logger.warning('Could not locate font %s, substituting default: %s',
fontname, default_fontname)
addition = ""
if " " in fontname:
addition = ". Your font contains spaces which is not valid in RML."
_logger.warning('Could not locate font %s, substituting default: %s%s',
fontname, default_fontname, addition)
fontname = default_fontname
return fontname