Browse Source

deep recursion conversion for objects

Davide Alberani 9 years ago
parent
commit
045cca48c0
5 changed files with 60 additions and 32 deletions
  1. 3 1
      angular_app/event-detail.html
  2. 17 5
      angular_app/js/controllers.js
  3. 30 21
      backend.py
  4. 3 3
      eventman_server.py
  5. 7 2
      utils.py

+ 3 - 1
angular_app/event-detail.html

@@ -72,7 +72,9 @@
                 <tbody>
                     <tr ng-repeat="person in event.persons | filter:query | orderBy:orderProp">
                         <td><a href="/#/persons/{{person.person_id}}">{{person.name}} {{person.surname}}</a></td>
-                        <td><span class="glyphicon {{(event.person_data && event.person_data.attended) && 'glyphicon-ok-sign' || 'glyphicon-remove-sign'}}"></span></td>
+                        <td>
+                                <button name="switch-attended" ng-click="updateAttendee(person, {attended: !person.attended})" class="btn btn-link glyphicon {{(person.attended) && 'glyphicon-ok-sign' || 'glyphicon-remove-sign'}}"></button>
+                        </td>
                     </tr>
                 </tbody>
             </table>

+ 17 - 5
angular_app/js/controllers.js

@@ -42,20 +42,32 @@ eventManControllers.controller('EventsListCtrl', ['$scope', 'Event',
 );
 
 
-eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$routeParams',
-    function ($scope, Event, $routeParams) {
+eventManControllers.controller('EventDetailsCtrl', ['$scope', 'Event', '$routeParams', '$log',
+    function ($scope, Event, $routeParams, $log) {
         if ($routeParams.id) {
             $scope.event = Event.get($routeParams);
         }
         // store a new Event or update an existing one
         $scope.save = function() {
-                if ($scope.event.id === undefined) {
-                    $scope.event = Event.save($scope.event);
+                var this_event = angular.copy($scope.event);
+                if (this_event.persons) {
+                    delete this_event.persons;
+                }
+                if (this_event.id === undefined) {
+                    $scope.event = Event.save(this_event);
                 } else {
-                    $scope.event = Event.update($scope.event);
+                    $scope.event = Event.update(this_event);
                 }
                 $scope.eventForm.$dirty = false;
         };
+
+        $scope.updateAttendee = function(person, data) {
+            $log.info('EventDetailsCtrl');
+            $log.info('event_id: ' + $routeParams.id);
+            $log.info('person_id: ' + person.person_id);
+            $log.info('data:');
+            $log.info(data);
+        };
     }]
 );
 

+ 30 - 21
backend.py

@@ -16,9 +16,11 @@ See the License for the specific language governing permissions and
 limitations under the License.
 """
 
+import re
 import pymongo
 from bson.objectid import ObjectId
 
+re_objectid = re.compile(r'[0-9a-f]{24}')
 
 class EventManDB(object):
     """MongoDB connector."""
@@ -54,18 +56,30 @@ class EventManDB(object):
         self.db = self.connection[self._dbName]
         return self.db
 
-    def toID(self, _id):
-        """Convert a string to a MongoDB ID.
+    def convert_obj(self, obj):
+        """Convert a string to an object for MongoDB.
 
-        :param _id: string to convert to :class:`~bson.objectid.ObjectId`
-        :type _id: str
-
-        :return: MongoDB ID
-        :rtype: :class:`~bson.objectid.ObjectId`
+        :param obj: object to convert
         """
-        if not isinstance(_id, ObjectId):
-            _id = ObjectId(_id)
-        return _id
+        try:
+            return ObjectId(obj)
+        except:
+            pass
+        try:
+            return int(obj)
+        except:
+            pass
+        return obj
+
+    def convert(self, seq):
+        if isinstance(seq, dict):
+            d = {}
+            for key, item in seq.iteritems():
+                d[key] = self.convert_obj(item)
+            return d
+        if isinstance(seq, (list, tuple)):
+            return [self.convert_obj(x) for x in seq]
+        return self.convert_obj(seq)
 
     def get(self, collection, _id):
         """Get a single document with the specified `_id`.
@@ -78,8 +92,7 @@ class EventManDB(object):
         :return: the document with the given `_id`
         :rtype: dict
         """
-        _id = self.toID(_id)
-        results = self.query(collection, {'_id': _id})
+        results = self.query(collection, self.convert({'_id': _id}))
         return results and results[0] or {}
 
     def query(self, collection, query=None):
@@ -94,13 +107,8 @@ class EventManDB(object):
         :rtype: list
         """
         db = self.connect()
-        query = query or {}
-        if'_id' in query:
-            query['_id'] = self.toID(query['_id'])
-        results = list(db[collection].find(query))
-        for result in results:
-            result['_id'] = str(result['_id'])
-        return results
+        query = self.convert(query or {})
+        return list(db[collection].find(query))
 
     def add(self, collection, data):
         """Insert a new document.
@@ -152,7 +160,8 @@ class EventManDB(object):
         elif isinstance(_id_or_query, (list, tuple)):
             _id_or_query = {'$or': self.buildSearchPattern(data, _id_or_query)}
         elif not isinstance(_id_or_query, dict):
-            _id_or_query = {'_id': self.toID(_id_or_query)}
+            _id_or_query = {'_id': _id_or_query}
+        _id_or_query = self.convert(_id_or_query)
         if '_id' in data:
             del data['_id']
         res = db[collection].find_and_modify(query=_id_or_query,
@@ -212,6 +221,6 @@ class EventManDB(object):
             return
         db = self.connect()
         if not isinstance(_id_or_query, dict):
-            _id_or_query = self.toID(_id_or_query)
+            _id_or_query = {'_id': _id_or_query}
         db[collection].remove(_id_or_query)
 

+ 3 - 3
eventman_server.py

@@ -99,7 +99,7 @@ class PersonsHandler(CollectionHandler):
     object_id = 'person_id'
 
     def handle_get_events(self, id_, **kwargs):
-        events = self.db.query('events', {'persons.person_id': self.db.toID(id_)})
+        events = self.db.query('events', {'persons.person_id': id_})
         for event in events:
             person_data = {}
             for persons in event.get('persons') or []:
@@ -161,8 +161,8 @@ class EbCSVImportPersonsHandler(BaseHandler):
                     if merged:
                         reply['merged'] += 1
                     if targetEvent and person:
-                        event_id = self.db.toID(targetEvent)
-                        person_id = self.db.toID(person['_id'])
+                        event_id = targetEvent
+                        person_id = person['_id']
                         registered_data = {
                                 'person_id': person_id,
                                 'attended': False,

+ 7 - 2
utils.py

@@ -16,6 +16,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 """
 
+import re
 import csv
 import json
 import datetime
@@ -72,13 +73,17 @@ def csvParse(csvStr, remap=None, merge=None):
 
 
 class ImprovedEncoder(json.JSONEncoder):
-    """Enhance the default JSON encoder to serialize datetime objects."""
+    """Enhance the default JSON encoder to serialize datetime and ObjectId instances."""
     def default(self, o):
         if isinstance(o, (datetime.datetime, datetime.date,
                 datetime.time, datetime.timedelta, ObjectId)):
-            return str(o)
+            try:
+                return str(o)
+            except Exception, e:
+                pass
         return json.JSONEncoder.default(self, o)
 
+
 # Inject our class as the default encoder.
 json._default_encoder = ImprovedEncoder()