Browse Source

refactory

Davide Alberani 9 years ago
parent
commit
4fa42a677a
5 changed files with 92 additions and 46 deletions
  1. 1 1
      angular_app/import-persons.html
  2. 3 3
      angular_app/person-detail.html
  3. 18 3
      backend.py
  4. 2 39
      eventman_server.py
  5. 68 0
      utils.py

+ 1 - 1
angular_app/import-persons.html

@@ -21,7 +21,7 @@
                 <input type="submit" value="{{'Import' | translate}}" ng-click="upload(file, '/ebcsvpersons')" />
 
                 <div class="form-group top5">
-                    Result: total: <span>{{reply.total}}</span> valid: <span>{{reply.valid}}</span>
+                    Result: total: <span>{{reply.total}}</span> valid: <span>{{reply.valid}}</span> merged: <span>{{reply.merged}}</span> new: <span>{{reply.valid - reply.merged}}</span>
                 </div>
             </form>
         </div>

+ 3 - 3
angular_app/person-detail.html

@@ -3,17 +3,17 @@
     <form ng-model="persondetails" ng-submit="save()">
         <div class="input-group input-group-lg">
             <span class="input-group-addon">Name</span>
-            <input type="text" class="form-control" placeholder="Name" value="{{person.name}}" ng-model="person.name" ng-required="1">
+            <input type="text" class="form-control" placeholder="Name" ng-model="person.name" ng-required="1">
         </div>
 
         <div class="input-group input-group-lg top5">
             <span class="input-group-addon">Surname</span>
-            <input type="text" class="form-control" placeholder="Surname" value="{{person.surname}}" ng-model="person.surname">
+            <input type="text" class="form-control" placeholder="Surname" ng-model="person.surname">
         </div>
 
         <div class="input-group top5">
             <span class="input-group-addon">Email</span>
-            <input type="email" class="form-control" placeholder="root@example.com" value="{{person.email}}" ng-model="person.email">
+            <input type="email" name="email" class="form-control" placeholder="root@example.com"  ng-model="person.email">
         </div>
 
         <input type="submit" style="position: absolute; left: -9999px; width: 1px; height: 1px;"/>

+ 18 - 3
backend.py

@@ -126,6 +126,16 @@ class EventManDB(object):
         return self.get(collection, _id)
 
     def merge(self, collection, data, searchBy):
+        """Update an existing document.
+
+        :param collection: update a document in this collection
+        :type collection: str
+        :param data: the document to store or merge with an existing one
+        :type data: dict
+
+        :return: a tuple with a boolean (True if an existing document was updated, and the _id of the document)
+        :rtype: tuple
+        """
         db = self.connect()
         _or = []
         for searchPattern in searchBy:
@@ -134,9 +144,14 @@ class EventManDB(object):
             except KeyError:
                 continue
         if not _or:
-            return {}
-        r = db[collection].update({'$or': _or}, {'$set': data}, upsert=True)
-        return r['updatedExisting']
+            return False, None
+        ret = db[collection].update({'$or': _or}, {'$set': data}, upsert=True)
+        _id = ret.get('upserted')
+        if _id is None:
+            newDoc = db[collection].find_one(data)
+            if newDoc:
+                _id = newDoc['_id']
+        return ret['updatedExisting'], _id
 
     def delete(self, collection, _id_or_query=None, force=False):
         """Remove one or more documents from a collection.

+ 2 - 39
eventman_server.py

@@ -18,9 +18,8 @@ limitations under the License.
 """
 
 import os
-import csv
 import json
-import StringIO
+import utils
 import datetime
 
 import tornado.httpserver
@@ -115,42 +114,6 @@ class ImportPersonsHandler(BaseHandler):
     pass
 
 
-def csvParse(csvStr, remap=None, merge=None):
-    fd = StringIO.StringIO(csvStr)
-    reader = csv.reader(fd)
-    remap = remap or {}
-    merge = merge or {}
-    fields = 0
-    reply = dict(total=0, valid=0)
-    results = []
-    try:
-        headers = reader.next()
-        fields = len(headers)
-    except (StopIteration, csv.Error):
-        return reply, {}
-
-    for idx, header in enumerate(headers):
-        if header in remap:
-            headers[idx] = remap[header]
-    try:
-        for row in reader:
-            try:
-                reply['total'] += 1
-                if len(row) != fields:
-                    continue
-                row = [unicode(cell, 'utf-8', 'replace') for cell in row]
-                values = dict(map(None, headers, row))
-                values.update(merge)
-                results.append(values)
-                reply['valid'] += 1
-            except csv.Error:
-                continue
-    except csv.Error:
-        pass
-    fd.close()
-    return reply, results
-
-
 class EbCSVImportPersonsHandler(ImportPersonsHandler):
     csvRemap = {
         'Nome evento': 'event_title',
@@ -178,7 +141,7 @@ class EbCSVImportPersonsHandler(ImportPersonsHandler):
         for fieldname, contents in self.request.files.iteritems():
             for content in contents:
                 filename = content['filename']
-                parseStats, persons = csvParse(content['body'], remap=self.csvRemap)
+                parseStats, persons = utils.csvParse(content['body'], remap=self.csvRemap)
                 reply['total'] += parseStats['total']
                 reply['valid'] += parseStats['valid']
                 for person in persons:

+ 68 - 0
utils.py

@@ -0,0 +1,68 @@
+"""Event Man(ager) utils
+
+Miscellaneous utilities.
+
+Copyright 2015 Davide Alberani <da@erlug.linux.it>
+               RaspiBO <info@raspibo.org>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+import csv
+import StringIO
+
+def csvParse(csvStr, remap=None, merge=None):
+    """Parse a CSV file, optionally renaming the columns and merging other information.
+
+    :param csvStr: the CSV to parse, as a string
+    :type csvStr: str
+    :param remap: a dictionary used to rename the columns
+    :type remap: dict
+    :param merge: merge these information into each line
+    :type merge: dict
+
+    :return: tuple with a dict of total and valid lines and the data
+    :rtype: tuple
+    """
+    fd = StringIO.StringIO(csvStr)
+    reader = csv.reader(fd)
+    remap = remap or {}
+    merge = merge or {}
+    fields = 0
+    reply = dict(total=0, valid=0)
+    results = []
+    try:
+        headers = reader.next()
+        fields = len(headers)
+    except (StopIteration, csv.Error):
+        return reply, {}
+
+    for idx, header in enumerate(headers):
+        if header in remap:
+            headers[idx] = remap[header]
+    try:
+        for row in reader:
+            try:
+                reply['total'] += 1
+                if len(row) != fields:
+                    continue
+                row = [unicode(cell, 'utf-8', 'replace') for cell in row]
+                values = dict(map(None, headers, row))
+                values.update(merge)
+                results.append(values)
+                reply['valid'] += 1
+            except csv.Error:
+                continue
+    except csv.Error:
+        pass
+    fd.close()
+    return reply, results
+