Thibault Delavallée (OpenERP) has proposed merging
lp:~openerp-dev/openobject-server/trunk-user_img-tde into lp:openobject-server.
Requested reviews:
OpenERP Core Team (openerp)
For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-user_img-tde/+merge/97184
User avatar
===========
This revision adds an avatar for users. This replaces the use of gravatar to
emulate avatars, used in views like the tasks kanban view. Two fields have been
added to the res.users model:
- avatar, a binary field holding the image
- avatar_mini, a binary field holding an automatically resized version of the
avatar. Dimensions of the resized avatar are 180x150.
User avatar has to be used everywhere an image depicting users is likely to be
used, by using the avatar_mini field.
An avatar field has been added to the users form view, as well as in
Preferences. When creating a new user, a default avatar is chosen among 6
possible default images.
--
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-user_img-tde/+merge/97184
Your team OpenERP R&D Team is subscribed to branch
lp:~openerp-dev/openobject-server/trunk-user_img-tde.
=== added file 'doc/api/user_img_specs.rst'
--- doc/api/user_img_specs.rst 1970-01-01 00:00:00 +0000
+++ doc/api/user_img_specs.rst 2012-03-13 10:45:56 +0000
@@ -0,0 +1,9 @@
+User avatar
+===========
+
+This revision adds an avatar for users. This replaces the use of gravatar to emulate avatars, used in views like the tasks kanban view. Two fields have been added to the res.users model:
+ - avatar, a binary field holding the image
+ - avatar_mini, a binary field holding an automatically resized version of the avatar. Dimensions of the resized avatar are 180x150.
+User avatar has to be used everywhere an image depicting users is likely to be used, by using the avatar_mini field.
+
+An avatar field has been added to the users form view, as well as in Preferences. When creating a new user, a default avatar is chosen among 6 possible default images.
=== modified file 'doc/index.rst.inc'
--- doc/index.rst.inc 2012-03-05 14:07:38 +0000
+++ doc/index.rst.inc 2012-03-13 10:45:56 +0000
@@ -6,3 +6,11 @@
:maxdepth: 1
test-framework
+
+New feature merges
+++++++++++++++++++
+
+.. toctree::
+ :maxdepth: 1
+
+ api/user_img_specs
=== modified file 'openerp/addons/base/base_update.xml'
--- openerp/addons/base/base_update.xml 2012-02-08 13:50:10 +0000
+++ openerp/addons/base/base_update.xml 2012-03-13 10:45:56 +0000
@@ -84,12 +84,18 @@
<form string="Users">
<field name="name" readonly="1"/>
<newline/>
- <group colspan="2" col="2">
- <separator string="Preferences" colspan="2"/>
- <field name="view" readonly="0"/>
- <field name="context_lang" readonly="0"/>
- <field name="context_tz" readonly="0"/>
- <field name="menu_tips" readonly="0" groups="base.group_no_one"/>
+ <group colspan="2" col="3">
+ <group col="2" colspan="2">
+ <separator string="Preferences" colspan="2"/>
+ <field name="view" readonly="0"/>
+ <field name="context_lang" readonly="0"/>
+ <field name="context_tz" readonly="0"/>
+ <field name="menu_tips" readonly="0" groups="base.group_no_one"/>
+ </group>
+ <group col="2" colspan="1">
+ <separator string="Avatar" colspan="2"/>
+ <field name="avatar" widget='image' nolabel="1" colspan="2"/>
+ </group>
</group>
<group name="default_filters" colspan="2" col="2">
<separator string="Default Filters" colspan="2"/>
@@ -118,32 +124,36 @@
</group>
<notebook colspan="4">
<page string="User">
- <group colspan="4" col="6">
- <!-- Second nested group to avoid misalignment with email prefs groups
- in simplified view -->
- <group colspan="6" col="6">
- <group col="2" colspan="2">
- <separator string="Preferences" colspan="2"/>
- <field name="context_lang"/>
- <field name="context_tz"/>
- <field name="menu_tips"/>
- </group>
- <group name="default_filters" colspan="2" col="2">
- <separator string="Default Filters" colspan="2"/>
- <field name="company_id" required="1" context="{'user_preference': 0}" groups="base.group_multi_company"/>
- </group>
- <group colspan="2" col="2" groups="base.group_extended">
- <separator string="Action" colspan="2"/>
- <field name="action_id"/>
- <field domain="[('usage','=','menu')]" name="menu_id" required="True"/>
- </group>
- </group>
- <group colspan="6" col="2">
- <separator string="Email Preferences" colspan="2"/>
- <field name="user_email" widget="email"/>
- <field name="signature"/>
- </group>
- </group>
+ <group colspan="4" col="7">
+ <!-- Second nested group to avoid misalignment with email prefs groups
+ in simplified view -->
+ <group colspan="7" col="7">
+ <group col="2" colspan="1">
+ <separator string="Avatar" colspan="2"/>
+ <field name="avatar_mini" widget='image' nolabel="1" colspan="2" on_change="onchange_avatar_mini(avatar_mini)"/>
+ </group>
+ <group col="3" colspan="2">
+ <separator string="Preferences" colspan="3"/>
+ <field name="context_lang"/>
+ <field name="context_tz"/>
+ <field name="menu_tips"/>
+ </group>
+ <group name="default_filters" colspan="2" col="2">
+ <separator string="Default Filters" colspan="2"/>
+ <field name="company_id" required="1" context="{'user_preference': 0}" groups="base.group_multi_company"/>
+ </group>
+ <group colspan="2" col="2" groups="base.group_extended">
+ <separator string="Action" colspan="2"/>
+ <field name="action_id"/>
+ <field domain="[('usage','=','menu')]" name="menu_id" required="True"/>
+ </group>
+ </group>
+ <group colspan="7" col="2">
+ <separator string="Email Preferences" colspan="2"/>
+ <field name="user_email" widget="email"/>
+ <field name="signature"/>
+ </group>
+ </group>
</page>
<page string="Access Rights">
<field nolabel="1" name="groups_id"/>
=== added directory 'openerp/addons/base/images'
=== added file 'openerp/addons/base/images/avatar0.jpg'
Binary files openerp/addons/base/images/avatar0.jpg 1970-01-01 00:00:00 +0000 and openerp/addons/base/images/avatar0.jpg 2012-03-13 10:45:56 +0000 differ
=== added file 'openerp/addons/base/images/avatar1.jpg'
Binary files openerp/addons/base/images/avatar1.jpg 1970-01-01 00:00:00 +0000 and openerp/addons/base/images/avatar1.jpg 2012-03-13 10:45:56 +0000 differ
=== added file 'openerp/addons/base/images/avatar2.jpg'
Binary files openerp/addons/base/images/avatar2.jpg 1970-01-01 00:00:00 +0000 and openerp/addons/base/images/avatar2.jpg 2012-03-13 10:45:56 +0000 differ
=== added file 'openerp/addons/base/images/avatar3.jpg'
Binary files openerp/addons/base/images/avatar3.jpg 1970-01-01 00:00:00 +0000 and openerp/addons/base/images/avatar3.jpg 2012-03-13 10:45:56 +0000 differ
=== added file 'openerp/addons/base/images/avatar4.jpg'
Binary files openerp/addons/base/images/avatar4.jpg 1970-01-01 00:00:00 +0000 and openerp/addons/base/images/avatar4.jpg 2012-03-13 10:45:56 +0000 differ
=== added file 'openerp/addons/base/images/avatar5.jpg'
Binary files openerp/addons/base/images/avatar5.jpg 1970-01-01 00:00:00 +0000 and openerp/addons/base/images/avatar5.jpg 2012-03-13 10:45:56 +0000 differ
=== added file 'openerp/addons/base/images/avatar6.jpg'
Binary files openerp/addons/base/images/avatar6.jpg 1970-01-01 00:00:00 +0000 and openerp/addons/base/images/avatar6.jpg 2012-03-13 10:45:56 +0000 differ
=== modified file 'openerp/addons/base/res/res_users.py'
--- openerp/addons/base/res/res_users.py 2012-02-13 18:32:07 +0000
+++ openerp/addons/base/res/res_users.py 2012-03-13 10:45:56 +0000
@@ -35,6 +35,12 @@
import openerp
import openerp.exceptions
+# for avatar resizing
+import io, StringIO
+from PIL import Image
+# for default avatar choice
+import random
+
_logger = logging.getLogger(__name__)
class groups(osv.osv):
@@ -200,7 +206,6 @@
self.write(cr, uid, ids, {'groups_id': [(4, extended_group_id)]}, context=context)
return True
-
def _get_interface_type(self, cr, uid, ids, name, args, context=None):
"""Implementation of 'view' function field getter, returns the type of interface of the users.
@param field_name: Name of the field
@@ -212,6 +217,29 @@
extended_users = group_obj.read(cr, uid, extended_group_id, ['users'], context=context)['users']
return dict(zip(ids, ['extended' if user in extended_users else 'simple' for user in ids]))
+ def onchange_avatar_mini(self, cr, uid, ids, value, context=None):
+ return {'value': {'avatar': value } }
+
+ def _set_avatar_mini(self, cr, uid, id, name, value, args, context=None):
+ return self.write(cr, uid, [id], {'avatar': value}, context=context)
+
+ def _avatar_resize(self, cr, uid, avatar, context=None):
+ image_stream = io.BytesIO(avatar.decode('base64'))
+ img = Image.open(image_stream)
+ img.thumbnail((180, 150), Image.ANTIALIAS)
+ img_stream = StringIO.StringIO()
+ img.save(img_stream, "JPEG")
+ return img_stream.getvalue().encode('base64')
+
+ def _get_avatar_mini(self, cr, uid, ids, name, args, context=None):
+ result = {}
+ for user in self.browse(cr, uid, ids, context=context):
+ if not user.avatar:
+ result[user.id] = False
+ else:
+ result[user.id] = self._avatar_resize(cr, uid, user.avatar)
+ return result
+
def _set_new_password(self, cr, uid, id, name, value, args, context=None):
if value is False:
# Do not update the password if no value is provided, ignore silently.
@@ -241,6 +269,11 @@
"otherwise leave empty. After a change of password, the user has to login again."),
'user_email': fields.char('Email', size=64),
'signature': fields.text('Signature', size=64),
+ 'avatar': fields.binary('User Avatar'),
+ 'avatar_mini': fields.function(_get_avatar_mini, fnct_inv=_set_avatar_mini, string='User Avatar Mini', type="binary",
+ store = {
+ 'res.users': (lambda self, cr, uid, ids, c={}: ids, ['avatar'], 10),
+ }),
'active': fields.boolean('Active'),
'action_id': fields.many2one('ir.actions.actions', 'Home Action', help="If specified, this action will be opened at logon for this user, in addition to the standard menu."),
'menu_id': fields.many2one('ir.actions.actions', 'Menu Action', help="If specified, the action will replace the standard menu for this user."),
@@ -352,9 +385,16 @@
pass
return result
+ def _get_avatar(self, cr, uid, context=None):
+ # default avatar file name: avatar0 -> avatar6, choose randomly
+ random.seed()
+ avatar_path = openerp.modules.get_module_resource('base', 'images', 'avatar%d.jpg' % random.randint(0, 6))
+ return self._avatar_resize(cr, uid, open(avatar_path, 'rb').read().encode('base64'))
+
_defaults = {
'password' : '',
'context_lang': 'en_US',
+ 'avatar_mini': _get_avatar,
'active' : True,
'menu_id': _get_menu,
'company_id': _get_company,
_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help : https://help.launchpad.net/ListHelp