[MERGE]from trunk

bzr revid: nch@tinyerp.com-20100706070658-t3yf4kfia1rfczyj
This commit is contained in:
nch@tinyerp.com 2010-07-06 12:36:58 +05:30
commit 877e3cc021
18 changed files with 104 additions and 87 deletions

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-addons\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-04-05 04:29+0000\n"
"Last-Translator: Ddorda <d.dorda@gmail.com>\n"
"PO-Revision-Date: 2010-07-04 04:21+0000\n"
"Last-Translator: Ilan <ilan@fonz.net>\n"
"Language-Team: Hebrew <he@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-06-23 03:48+0000\n"
"X-Launchpad-Export-Date: 2010-07-05 03:46+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@ -315,7 +315,7 @@ msgstr "מודולים לא מותקנים"
#. module: base
#: selection:ir.actions.report.xml,report_type:0
msgid "txt"
msgstr ""
msgstr "txt"
#. module: base
#: wizard_view:server.action.create,init:0

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-07-01 04:24+0000\n"
"PO-Revision-Date: 2010-07-05 04:22+0000\n"
"Last-Translator: Goran Kliska <gkliska@gmail.com>\n"
"Language-Team: openerp-translators\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-07-02 03:32+0000\n"
"X-Launchpad-Export-Date: 2010-07-06 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
"Language: hr\n"

View File

@ -8,13 +8,13 @@ msgstr ""
"Project-Id-Version: openobject-server\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-07-01 04:23+0000\n"
"PO-Revision-Date: 2010-07-05 04:25+0000\n"
"Last-Translator: Harry (Open ERP) <hmo@tinyerp.com>\n"
"Language-Team: Japanese <ja@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-07-02 03:32+0000\n"
"X-Launchpad-Export-Date: 2010-07-06 03:36+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-07-01 04:21+0000\n"
"PO-Revision-Date: 2010-07-05 04:29+0000\n"
"Last-Translator: Anders Wallenquist <anders.wallenquist@vertel.se>\n"
"Language-Team: <>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-07-02 03:32+0000\n"
"X-Launchpad-Export-Date: 2010-07-06 03:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-07-01 04:25+0000\n"
"PO-Revision-Date: 2010-07-05 04:19+0000\n"
"Last-Translator: Fabien (Open ERP) <fp@tinyerp.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-07-02 03:32+0000\n"
"X-Launchpad-Export-Date: 2010-07-06 03:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.4\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-12-18 08:39+0000\n"
"PO-Revision-Date: 2010-07-01 04:23+0000\n"
"PO-Revision-Date: 2010-07-05 04:25+0000\n"
"Last-Translator: Eleanor Chen <chenyueg@gmail.com>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2010-07-02 03:32+0000\n"
"X-Launchpad-Export-Date: 2010-07-06 03:37+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base

View File

@ -1481,7 +1481,7 @@
</field>
</record>
<record id="act_ir_actions_todo_form" model="ir.actions.act_window">
<field name="name">List of Configuration Wizards</field>
<field name="name">Configuration Wizards</field>
<field name="res_model">ir.actions.todo</field>
<field name="view_id" ref="ir_actions_todo_tree"/>
<field name="view_type">form</field>
@ -1489,7 +1489,7 @@
<menuitem id="next_id_11" name="Configuration Wizards" parent="base.menu_config" sequence="1"/>
<menuitem action="act_ir_actions_todo_form" id="menu_ir_actions_todo_form"
parent="base.next_id_4" groups="base.group_extended" sequence="20"/>
parent="next_id_11" groups="base.group_extended" sequence="20"/>
<record id="action_start_configurator" model="ir.actions.server">
<field name="name">Launch Configuration Wizards</field>

View File

@ -242,13 +242,19 @@ class act_window(osv.osv):
'name': fields.char('Action Name', size=64, translate=True),
'type': fields.char('Action Type', size=32, required=True),
'view_id': fields.many2one('ir.ui.view', 'View Ref.', ondelete='cascade'),
'domain': fields.char('Domain Value', size=250),
'context': fields.char('Context Value', size=250),
'res_model': fields.char('Object', size=64),
'src_model': fields.char('Source Object', size=64),
'domain': fields.char('Domain Value', size=250,
help="Optional domain filtering of the destination data, as a Python expression"),
'context': fields.char('Context Value', size=250, required=True,
help="Context dictionary as Python expression, empty by default (Default: {})"),
'res_model': fields.char('Object', size=64, required=True,
help="Model name of the object to open in the view window"),
'src_model': fields.char('Source Object', size=64,
help="Optional model name of the objects on which this action should be visible"),
'target': fields.selection([('current','Current Window'),('new','New Window')], 'Target Window'),
'view_type': fields.selection((('tree','Tree'),('form','Form')),string='View Type'),
'view_mode': fields.char('View Mode', size=250),
'view_type': fields.selection((('tree','Tree'),('form','Form')), string='View Type', required=True,
help="View type: set to 'tree' for a hierarchical tree view, or 'form' for other views"),
'view_mode': fields.char('View Mode', size=250, required=True,
help="Comma-separated list of allowed view modes, such as 'form', 'tree', 'calendar', etc. (Default: tree,form)"),
'usage': fields.char('Action Usage', size=32),
'view_ids': fields.one2many('ir.actions.act_window.view', 'act_window_id', 'Views'),
'views': fields.function(_views_get_fnc, method=True, type='binary', string='Views'),
@ -263,8 +269,10 @@ class act_window(osv.osv):
'default_user_ids': fields.many2many('res.users', 'ir_act_window_user_rel', 'act_id', 'uid', 'Users'),
'search_view' : fields.function(_search_view, type='text', method=True, string='Search View'),
'menus': fields.char('Menus', size=4096),
'help': fields.text('Action description'),
'help': fields.text('Action description',
help='Optional help text for the users with a description of the target view, such as its usage and purpose.'),
'display_help':fields.function(_get_help_status, type='boolean', method=True, string='Display Help')
}
_defaults = {
'type': lambda *a: 'ir.actions.act_window',

View File

@ -244,7 +244,7 @@ class ir_model_fields(osv.osv):
_description = "Fields"
_columns = {
'name': fields.char('Name', required=True, size=64, select=1),
'model': fields.char('Object Name', size=64, required=True),
'model': fields.char('Object Name', size=64, required=True, select=1),
'relation': fields.char('Object Relation', size=64),
'relation_field': fields.char('Relation Field', size=64),
'model_id': fields.many2one('ir.model', 'Object ID', required=True, select=True, ondelete='cascade'),
@ -256,7 +256,7 @@ class ir_model_fields(osv.osv):
'select_level': fields.selection([('0','Not Searchable'),('1','Always Searchable'),('2','Advanced Search')],'Searchable', required=True),
'translate': fields.boolean('Translate'),
'size': fields.integer('Size'),
'state': fields.selection([('manual','Custom Field'),('base','Base Field')],'Manually Created', required=True, readonly=True),
'state': fields.selection([('manual','Custom Field'),('base','Base Field')],'Manually Created', required=True, readonly=True, select=1),
'on_delete': fields.selection([('cascade','Cascade'),('set null','Set NULL')], 'On delete', help='On delete property for many2one fields'),
'domain': fields.char('Domain', size=256),
'groups': fields.many2many('res.groups', 'ir_model_fields_group_rel', 'field_id', 'group_id', 'Groups'),
@ -321,9 +321,9 @@ ir_model_fields()
class ir_model_access(osv.osv):
_name = 'ir.model.access'
_columns = {
'name': fields.char('Name', size=64, required=True),
'model_id': fields.many2one('ir.model', 'Object', required=True, domain=[('osv_memory','=', False)]),
'group_id': fields.many2one('res.groups', 'Group', ondelete='cascade'),
'name': fields.char('Name', size=64, required=True, select=True),
'model_id': fields.many2one('ir.model', 'Object', required=True, domain=[('osv_memory','=', False)], select=True),
'group_id': fields.many2one('res.groups', 'Group', ondelete='cascade', select=True),
'perm_read': fields.boolean('Read Access'),
'perm_write': fields.boolean('Write Access'),
'perm_create': fields.boolean('Create Access'),
@ -462,10 +462,10 @@ class ir_model_data(osv.osv):
_name = 'ir.model.data'
__logger = logging.getLogger('addons.base.'+_name)
_columns = {
'name': fields.char('XML Identifier', required=True, size=128),
'model': fields.char('Object', required=True, size=64),
'module': fields.char('Module', required=True, size=64),
'res_id': fields.integer('Resource ID'),
'name': fields.char('XML Identifier', required=True, size=128, select=1),
'model': fields.char('Object', required=True, size=64, select=1),
'module': fields.char('Module', required=True, size=64, select=1),
'res_id': fields.integer('Resource ID', select=1),
'noupdate': fields.boolean('Non Updatable'),
'date_update': fields.datetime('Update Date'),
'date_init': fields.datetime('Init Date')

View File

@ -109,7 +109,6 @@ class ir_translation(osv.osv):
'and name=%s ' \
'and res_id IN %s',
(lang,tt,name,tuple(ids),))
cr.commit()
for id in ids:
self.create(cr, uid, {
'lang':lang,

View File

@ -25,30 +25,25 @@ import os
import tools
view_form_end = """<?xml version="1.0"?>
<form string="System upgrade done">
<separator string="System upgrade done"/>
<label align="0.0" string="The modules have been upgraded / installed !" colspan="4"/>
<label align="0.0" string="We suggest you to reload the menu tab (Ctrl+t Ctrl+r)." colspan="4"/>
<form string="System update done">
<separator string="System update completed"/>
<label align="0.0" string="The selected modules have been updated / installed !" colspan="4"/>
<label align="0.0" string="We suggest to reload the menu tab to see the new menus (Ctrl+T then Ctrl+R)." colspan="4"/>
</form>"""
view_form = """<?xml version="1.0"?>
<form string="System Upgrade">
<form string="System Update">
<image name="gtk-dialog-info" colspan="2"/>
<group colspan="2" col="4">
<label align="0.0" string="Your system will be upgraded." colspan="4"/>
<label align="0.0" string="Note that this operation my take a few minutes." colspan="4"/>
<label align="0.0" string="Your system will be updated." colspan="4"/>
<label align="0.0" string="Note that this operation might take a few minutes." colspan="4"/>
<separator string="Modules to update"/>
<field name="module_info" nolabel="1" colspan="4"/>
<separator string="Modules to download"/>
<field name="module_download" nolabel="1" colspan="4"/>
</group>
</form>"""
view_field = {
"module_info": {'type': 'text', 'string': 'Modules to update',
'readonly': True},
"module_download": {'type': 'text', 'string': 'Modules to download',
'readonly': True},
"module_info": {'type': 'text', 'string': 'Modules to update', 'readonly': True},
}
class wizard_info_get(wizard.interface):
@ -58,9 +53,7 @@ class wizard_info_get(wizard.interface):
ids = mod_obj.search(cr, uid, [
('state', 'in', ['to upgrade', 'to remove', 'to install'])])
res = mod_obj.read(cr, uid, ids, ['name','state'], context)
url = mod_obj.download(cr, uid, ids, download=False, context=context)
return {'module_info': '\n'.join(map(lambda x: x['name']+' : '+x['state'], res)),
'module_download': '\n'.join(url)}
return {'module_info': '\n'.join(map(lambda x: x['name']+' : '+x['state'], res))}
def _check_upgrade_module(self,cr,uid,data,context):
pool = pooler.get_pool(cr.dbname)
@ -104,7 +97,7 @@ class wizard_info_get(wizard.interface):
'result': {'type':'form', 'arch':view_form, 'fields': view_field,
'state':[
('end', 'Cancel', 'gtk-cancel'),
('start', 'Start Upgrade', 'gtk-ok', True)
('start', 'Start update', 'gtk-ok', True)
]
}
},
@ -144,9 +137,7 @@ class wizard_info_get_simple(wizard.interface):
ids = mod_obj.search(cr, uid, [
('state', 'in', ['to upgrade', 'to remove', 'to install'])])
res = mod_obj.read(cr, uid, ids, ['name','state'], context)
url = mod_obj.download(cr, uid, ids, download=False, context=context)
return {'module_info': '\n'.join(map(lambda x: x['name']+' : '+x['state'], res)),
'module_download': '\n'.join(url)}
return {'module_info': '\n'.join(map(lambda x: x['name']+' : '+x['state'], res)),}
def _check_upgrade_module(self,cr,uid,data,context):
pool = pooler.get_pool(cr.dbname)
@ -170,7 +161,7 @@ class wizard_info_get_simple(wizard.interface):
if dep_mod.state in ('unknown','uninstalled'):
unmet_packages.append(dep_mod.name)
if len(unmet_packages):
raise wizard.except_wizard('Unmet dependency !', 'Following modules are uninstalled or unknown. \n\n'+'\n'.join(unmet_packages))
raise wizard.except_wizard('Unmet dependencies!', 'The following modules are not installed or unavailable. \n\n'+'\n'.join(unmet_packages))
mod_obj.download(cr, uid, ids, context=context)
cr.commit()
db, pool = pooler.restart_pool(cr.dbname, update_module=True)
@ -190,7 +181,7 @@ class wizard_info_get_simple(wizard.interface):
'result': {'type':'form', 'arch':view_form, 'fields': view_field,
'state':[
('end', 'Cancel', 'gtk-cancel'),
('start', 'Start Upgrade', 'gtk-ok', True)
('start', 'Start update', 'gtk-ok', True)
]
}
},

View File

@ -113,8 +113,15 @@ if not ( tools.config["stop_after_init"] or \
service.netrpc_server.init_servers()
if tools.config['db_name']:
for db in tools.config['db_name'].split(','):
pooler.get_db_and_pool(db, update_module=tools.config['init'] or tools.config['update'])
for dbname in tools.config['db_name'].split(','):
db,pool = pooler.get_db_and_pool(dbname, update_module=tools.config['init'] or tools.config['update'], pooljobs=False)
if tools.config["test-file"]:
logger.notifyChannel("init", netsvc.LOG_INFO,
'loading test file %s' % (tools.config["test-file"],))
cr = db.cursor()
tools.convert_yaml_import(cr, 'base', file(tools.config["test-file"]), {}, 'test', True)
cr.rollback()
pool.get('ir.cron')._poolJobs(db.dbname)
#----------------------------------------------------------
# translation stuff

View File

@ -1767,7 +1767,7 @@ class orm_memory(orm_template):
for id in self.datas:
if self.datas[id]['internal.date_access'] < max:
tounlink.append(id)
self.unlink(cr, uid, tounlink)
self.unlink(cr, 1, tounlink)
if len(self.datas)>self._max_count:
sorted = map(lambda x: (x[1]['internal.date_access'], x[0]), self.datas.items())
sorted.sort()
@ -2382,6 +2382,8 @@ class orm(orm_template):
break
i+=1
logger.notifyChannel('orm', netsvc.LOG_WARNING, "column '%s' in table '%s' has changed type (DB=%s, def=%s), data moved to table %s !" % (k, self._table, f_pg_type, f._type, newname))
if f_pg_notnull:
cr.execute('ALTER TABLE "%s" ALTER COLUMN "%s" DROP NOT NULL' % (self._table, k))
cr.execute('ALTER TABLE "%s" RENAME COLUMN "%s" TO "%s"' % (self._table, k, newname))
cr.execute('ALTER TABLE "%s" ADD COLUMN "%s" %s' % (self._table, k, get_pg_type(f)[1]))
cr.execute("COMMENT ON COLUMN %s.%s IS '%s'" % (self._table, k, f.string.replace("'","''")))

View File

@ -21,7 +21,7 @@
pool_dic = {}
def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False):
def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False, pooljobs=True):
if not status:
status={}
@ -50,7 +50,8 @@ def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False)
import report
report.interface.register_all(db)
pool.get('ir.cron')._poolJobs(db.dbname)
if pooljobs:
pool.get('ir.cron')._poolJobs(db.dbname)
return db, pool

View File

@ -232,7 +232,7 @@ class report_printscreen_list(report_int):
col.set('tree','float')
if tsum[f] != None:
if tsum[f] >= 0.01 :
prec = '%.' + str(tools.config['price_accuracy']) + 'f'
prec = '%.2f'
total = prec%(tsum[f])
txt = str(total or '')
else:

View File

@ -75,7 +75,6 @@ class configmanager(object):
'smtp_ssl':False,
'smtp_password': False,
'stop_after_init': False, # this will stop the server after initialization
'price_accuracy': 2,
'syslog' : False,
'log_level': logging.INFO,
'assert_exit_level': logging.ERROR, # level above which a failed assert will be raised
@ -83,6 +82,7 @@ class configmanager(object):
'login_message': False,
'list_db' : True,
'timezone' : False, # to override the default TZ
'test-file' : False,
'test-disable' : False,
'test-commit' : False,
}
@ -141,10 +141,10 @@ class configmanager(object):
parser.add_option('--debug', dest='debug_mode', action='store_true', default=False, help='enable debug mode')
parser.add_option("--assert-exit-level", dest='assert_exit_level', type="choice", choices=self._LOGLEVELS.keys(),
help="specify the level at which a failed assertion will stop the server. Accepted values: %s" % (self._LOGLEVELS.keys(),))
parser.add_option('--price_accuracy', dest='price_accuracy', default='2', help='deprecated since v6.0, replaced by module decimal_precision')
# Testing Group
group = optparse.OptionGroup(parser, "Testing Configuration")
group.add_option("--test-file", dest="test_file", help="Launch a YML test file.")
group.add_option("--test-disable", action="store_true", dest="test_disable",
default=False, help="Disable loading test files.")
group.add_option("--test-commit", action="store_true", dest="test_commit",
@ -257,7 +257,7 @@ class configmanager(object):
keys = ['xmlrpc_interface', 'xmlrpc_port', 'db_name', 'db_user', 'db_password', 'db_host',
'db_port', 'list_db', 'logfile', 'pidfile', 'smtp_port', 'cache_timeout','smtp_ssl',
'email_from', 'smtp_server', 'smtp_user', 'smtp_password', 'price_accuracy',
'email_from', 'smtp_server', 'smtp_user', 'smtp_password',
'netrpc_interface', 'netrpc_port', 'db_maxconn', 'import_partial', 'addons_path',
'netrpc', 'xmlrpc', 'syslog', 'without_demo', 'timezone',
'xmlrpcs_interface', 'xmlrpcs_port', 'xmlrpcs',
@ -295,6 +295,7 @@ class configmanager(object):
self.options['init'] = opt.init and dict.fromkeys(opt.init.split(','), 1) or {}
self.options["demo"] = not opt.without_demo and self.options['init'] or {}
self.options["test-file"] = opt.test_file
self.options["test-disable"] = opt.test_disable
self.options["test-commit"] = opt.test_commit
self.options['update'] = opt.update and dict.fromkeys(opt.update.split(','), 1) or {}
@ -470,5 +471,3 @@ config = configmanager()
# other python executables without parsing *their* args.
config.parse_config()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -349,7 +349,6 @@ def html2plaintext(html, body_id=None, encoding='utf-8'):
"""
html = ustr(html)
urls = []
from lxml.etree import Element, tostring
try:
@ -376,7 +375,6 @@ def html2plaintext(html, body_id=None, encoding='utf-8'):
url = link.get('href')
if url:
i += 1
urls.append(dict(url=ustr(url), tag=ustr(link), title=ustr(title)))
link.tag = 'span'
link.text = '%s [%s]' % (link.text, i)
url_index.append(url)
@ -822,49 +820,61 @@ class cache(object):
def to_xml(s):
return s.replace('&','&amp;').replace('<','&lt;').replace('>','&gt;')
def get_encodings():
yield 'utf8'
def get_encodings(hint_encoding='utf-8'):
fallbacks = {
'latin1': 'latin9',
'iso-8859-1': 'iso8859-15',
'cp1252': '1252',
}
if hint_encoding:
yield hint_encoding
if hint_encoding.lower() in fallbacks:
yield fallbacks[hint_encoding.lower()]
# some defaults (also taking care of pure ASCII)
for charset in ['utf8','latin1']:
if not (hint_encoding) or (charset.lower() != hint_encoding.lower()):
yield charset
from locale import getpreferredencoding
prefenc = getpreferredencoding()
if prefenc:
if prefenc and prefenc.lower() != 'utf-8':
yield prefenc
prefenc = {
'latin1': 'latin9',
'iso-8859-1': 'iso8859-15',
'cp1252': '1252',
}.get(prefenc.lower())
prefenc = fallbacks.get(prefenc.lower())
if prefenc:
yield prefenc
def ustr(value):
def ustr(value, hint_encoding='utf-8'):
"""This method is similar to the builtin `str` method, except
it will return Unicode string.
it will return unicode() string.
@param value: the value to convert
@param hint_encoding: an optional encoding that was detected
upstream and should be tried first to
decode ``value``.
@rtype: unicode
@return: unicode string
"""
orig = value
if isinstance(value, Exception):
return exception_to_unicode(value)
if isinstance(value, unicode):
return value
try:
return unicode(value)
except Exception:
pass
if not isinstance(value, basestring):
try:
return unicode(value)
except Exception:
raise UnicodeError('unable de to convert %r' % (value,))
for ln in get_encodings():
for ln in get_encodings(hint_encoding):
try:
return unicode(value, ln)
except Exception:
pass
raise UnicodeError('unable de to convert %r' % (orig,))
raise UnicodeError('unable de to convert %r' % (value,))
def exception_to_unicode(e):

View File

@ -28,5 +28,5 @@
#
##############################################################################
./module_graph.py $@ | dot -Tpng -o > module_graph.png
`dirname $0`/module_graph.py $@ | dot -Tpng -o > module_graph.png