r252663 - atreal.usersinout/branches/redturtle/1.2.2/atreal/usersinout/browser
"Luca Bellenghi" <svn-changes-z4DKO/[email protected]> Tue, 29 Oct 2013 13:07:57 +0000 (UTC)
| Newsgroups | gmane.comp.web.zope.plone.collective.cvs |
|---|---|
| Message-ID | <[email protected]> |
Author: lucabel
Date: Tue Oct 29 13:07:57 2013
New Revision: 252663
Modified:
atreal.usersinout/branches/redturtle/1.2.2/atreal/usersinout/browser/usersinout.pt
atreal.usersinout/branches/redturtle/1.2.2/atreal/usersinout/browser/usersinout.py
Log:
update user import method
Modified: atreal.usersinout/branches/redturtle/1.2.2/atreal/usersinout/browser/usersinout.pt
==============================================================================
--- atreal.usersinout/branches/redturtle/1.2.2/atreal/usersinout/browser/usersinout.pt (original)
+++ atreal.usersinout/branches/redturtle/1.2.2/atreal/usersinout/browser/usersinout.pt Tue Oct 29 13:07:57 2013
@@ -15,7 +15,7 @@
<h1 class="documentFirstHeading"
i18n:translate="">
- Users In/Out
+ Users Import
</h1>
<tal:trans i18n:domain="plone">
@@ -28,7 +28,7 @@
</tal:trans>
<p class="discreet" i18n:translate="">
- Users import and export as CSV files.
+ Users import as CSV files.
</p>
<form method="POST" action="#" enctype="multipart/form-data"
@@ -55,6 +55,9 @@
</a>
</tal:trans>
</div>
+ <div class="formHelp" i18n:translate="">
+ Please remember that first_name, last_name, company, personal_email and fixed_position are mandatory
+ </div>
<input type="file" name="csv_upload" />
</div>
@@ -78,7 +81,7 @@
</fieldset>
- <fieldset tal:condition="python:'users_results' in view.request">
+ <fieldset tal:condition="nothing">
<legend i18n:translate="">
Results
</legend>
@@ -121,7 +124,7 @@
- <fieldset>
+ <fieldset tal:condition="nothing">
<legend i18n:translate="">
Export
</legend>
Modified: atreal.usersinout/branches/redturtle/1.2.2/atreal/usersinout/browser/usersinout.py
==============================================================================
--- atreal.usersinout/branches/redturtle/1.2.2/atreal/usersinout/browser/usersinout.py (original)
+++ atreal.usersinout/branches/redturtle/1.2.2/atreal/usersinout/browser/usersinout.py Tue Oct 29 13:07:57 2013
@@ -7,15 +7,78 @@
from Products.Five.browser import BrowserView
from Products.CMFCore.utils import getToolByName
from Products.statusmessages.interfaces import IStatusMessage
+from plone.app.users.userdataschema import IUserDataSchemaProvider
+from zope.component import getUtility, getAdapter
+from zope.schema import getFieldNamesInOrder
from atreal.usersinout import UsersInOutMessageFactory as _
-from atreal.usersinout.config import CSV_HEADER, MEMBER_PROPERTIES
+from movingfluid.policy.config import USER_TAGS, COMPANY_POSITIONS
+
+CSV_HEADER = [
+ 'password',
+ 'first_name',
+ 'last_name',
+ 'company',
+ 'position',
+ 'fixed_position',
+ 'group',
+ 'working_from',
+ 'personal_email',
+ 'country',
+ 'address',
+ 'city',
+ 'province',
+ 'zip_code',
+ 'phone',
+ 'personal_phone',
+ 'twitter',
+ 'facebook','linkedin',
+ 'birthdate',
+ 'hobbies',
+ 'previous_companies',
+ 'mf_reference',
+ 'description',
+]
+
+MEMBER_PROPERTIES = [
+ 'first_name',
+ 'last_name',
+ 'company',
+ 'position',
+ 'fixed_position',
+ 'group',
+ 'working_from',
+ 'personal_email',
+ 'country',
+ 'address',
+ 'city',
+ 'province',
+ 'zip_code',
+ 'phone',
+ 'personal_phone',
+ 'twitter',
+ 'facebook',
+ 'linkedin',
+ 'birthdate',
+ 'hobbies',
+ 'previous_companies',
+ 'mf_reference',
+ 'description'
+]
class UsersInOut (BrowserView):
"""Users import and export as CSV files.
"""
+ def _redirect(self, msg='', msg_type='info'):
+ if self.request:
+ if msg:
+ IStatusMessage(self.request).addStatusMessage(msg, msg_type)
+ self.request.response.redirect(self.context.absolute_url() +
+ '/@@usersinout-controlpanel')
+ return msg
+
def __call__(self):
method = self.request.get('REQUEST_METHOD', 'GET')
if (method != 'POST') or not int(self.request.form.get('form.submitted', 0)):
@@ -51,68 +114,85 @@
reader = csv.reader(file_upload)
header = reader.next()
+ if type(header) == list:
+ header = header[0].split(';')
if header != CSV_HEADER:
msg = _('Wrong specification of the CSV file. Please correct it and retry.')
- type = 'error'
- IStatusMessage(self.request).addStatusMessage(msg, type=type)
+ msg_type = 'error'
+ self._redirect(msg, msg_type)
return
pr = getToolByName(self.context, 'portal_registration')
- pg = getToolByName(self.context, 'portal_groups')
+ mt = getToolByName(self.context, 'portal_membership')
acl = getToolByName(self.context,'acl_users')
- groupsIds = set([item['id'] for item in acl.searchGroups()])
- groupsDict = {}
+ portal = getToolByName(self.context, 'portal_url').getPortalObject()
invalidLines = []
validLines = []
-
- groupsNumber = 0
+ counter = 1 # line 0 is header
for line in reader:
+ if type(line) == list:
+ line = line[0].split(';')
datas = dict(zip(header, line))
- try:
- groups = [g.strip() for g in datas.pop('groups').split(',') if g]
- for group in groups:
- if not group in groupsIds: # New group, 'have to create it
- pg.addGroup(group)
- groupsNumber += 1
-
- except:
+ if not (datas['first_name'] and datas['last_name'] and \
+ datas['company'] and datas['personal_email'] and \
+ datas['fixed_position']):
+ msg = _("User at line %s is wrong, please correct it" % counter)
+ IStatusMessage(self.request).addStatusMessage(msg, 'error')
+ invalidLines.append(line)
+ if datas['fixed_position'] and\
+ datas['fixed_position'] not in COMPANY_POSITIONS:
+ msg = _("User entry at line %s is wrong: position is not ceo neither cto" % counter)
+ IStatusMessage(self.request).addStatusMessage(msg, 'error')
+ invalidLines.append(line)
+ if datas['group'] and datas['group'] not in USER_TAGS:
+ msg = _("User entry at line %s is wrong: group is not valid" % counter)
+ IStatusMessage(self.request).addStatusMessage(msg, 'error')
invalidLines.append(line)
- print "Invalid line: %s" % line
- continue
- validLines.append(line)
+
+ validLines.append(datas)
+ counter += 1
+
+ #Se arriviamo qui non dobbiamo avere
+ if invalidLines:
+ msg = _("CSV file is not properly compiled: some mandatory field is missing or some field value is wrong")
+ self._redirect(msg, 'error')
+ return
usersNumber = 0
for line in validLines:
- datas = dict(zip(header, line))
try:
- groups = [g.strip() for g in datas.pop('groups').split(',') if g]
- username = datas['username']
- password = datas.pop('password')
- roles = datas.pop('roles').split(',')
- pr.addMember(username, password, roles, [], datas)
- for group in groups:
- if not group in groupsDict.keys():
- groupsDict[group] = acl.getGroupById(group)
- groupsDict[group].addMember(username)
+ username = line['personal_email']
+ password = line.pop('password')
+ roles = ['Member',]
+ pr.addMember(username, password, roles, [])
+
+ schema = getUtility(IUserDataSchemaProvider).getSchema()
+ adapter = getAdapter(portal, schema)
+ member = mt.getMemberById(line['personal_email'])
+ adapter.context = member
+
+ for name in getFieldNamesInOrder(schema):
+ if name in line:
+ setattr(adapter, name, line[name])
usersNumber += 1
- except:
+ except ValueError, err_msg:
+ msg = "%s: %s" % (line['personal_email'], err_msg.message)
+ IStatusMessage(self.request).addStatusMessage(msg, 'error')
+ invalidLines.append(line)
+ except Exception, err_msg:
invalidLines.append(line)
print "Invalid line: %s" % line
if invalidLines:
- datafile = self._createCSV(invalidLines)
- self.request['csverrors'] = True
- self.request.form['users_sheet_errors'] = datafile.getvalue()
msg = _('Some errors occured. Please check your CSV syntax and retry.')
- type = 'error'
+ msg_type = 'error'
else:
- msg, type = _('Members successfully imported.'), 'info'
+ msg, msg_type = _('Members successfully imported.'), 'info'
- IStatusMessage(self.request).addStatusMessage(msg, type=type)
self.request['users_results'] = usersNumber
- self.request['groups_results'] = groupsNumber
- return self.index()
+ self._redirect(msg, msg_type)
+ return
def getCSVWithErrors(self):
"""Return a CSV file that contains lines witch failed."""
@@ -122,38 +202,38 @@
return # XXX
return self._createRequest(users_sheet_errors, "users_sheet_errors.csv")
- def exportUsers(self):
- """Export users within CSV file."""
- self.pms = getToolByName(self.context,'portal_membership')
- pg = getToolByName(self.context,'portal_groups')
- acl = getToolByName(self.context,'acl_users')
- gids = set([item['id'] for item in acl.searchGroups()])
- self.group_roles = {}
- for gid in gids:
- self.group_roles[gid] = pg.getGroupById(gid).getRoles()
- datafile = self._createCSV(self._getUsersInfos())
- return self._createRequest(datafile.getvalue(), "users_sheet_export.csv")
-
- def _getUsersInfos(self):
- """Generator filled with the members data."""
- acl = getToolByName(self.context, 'acl_users')
- for user in acl.searchUsers():
- if not user['pluginid'] == 'mutable_properties':
- yield self._getUserData(user['userid'])
-
- def _getUserData(self,userId):
- member = self.pms.getMemberById(userId)
- groups = member.getGroups()
- group_roles = []
- for gid in groups:
- group_roles.extend(self.group_roles.get(gid, []))
- roles = [role for role in member.getRoles() if not role in group_roles]
- props = [userId, '', ','.join(roles)] # userid, password, roles
- if member is not None:
- for p in MEMBER_PROPERTIES:
- props.append(member.getProperty(p))
- props.append(','.join(groups)) # groups
- return props
+# def exportUsers(self):
+# """Export users within CSV file."""
+# self.pms = getToolByName(self.context,'portal_membership')
+# pg = getToolByName(self.context,'portal_groups')
+# acl = getToolByName(self.context,'acl_users')
+# gids = set([item['id'] for item in acl.searchGroups()])
+# self.group_roles = {}
+# for gid in gids:
+# self.group_roles[gid] = pg.getGroupById(gid).getRoles()
+# datafile = self._createCSV(self._getUsersInfos())
+# return self._createRequest(datafile.getvalue(), "users_sheet_export.csv")
+
+# def _getUsersInfos(self):
+# """Generator filled with the members data."""
+# acl = getToolByName(self.context, 'acl_users')
+# for user in acl.searchUsers():
+# if not user['pluginid'] == 'mutable_properties':
+# yield self._getUserData(user['userid'])
+
+# def _getUserData(self,userId):
+# member = self.pms.getMemberById(userId)
+# groups = member.getGroups()
+# group_roles = []
+# for gid in groups:
+# group_roles.extend(self.group_roles.get(gid, []))
+# roles = [role for role in member.getRoles() if not role in group_roles]
+# props = [userId, '', ','.join(roles)] # userid, password, roles
+# if member is not None:
+# for p in MEMBER_PROPERTIES:
+# props.append(member.getProperty(p))
+# props.append(','.join(groups)) # groups
+# return props
def _createCSV(self, lines):
"""Write header and lines within the CSV file."""
------------------------------------------------------------------------------
Android is increasing in popularity, but the open development platform that
developers love is also attractive to malware creators. Download this white
paper to learn more about secure code signing practices that can help keep
Android apps secure.
http://pubads.g.doubleclick.net/gampad/clk?id=65839951&iu=/4140/ostg.clktrk