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