From 9bace889d54f9898938f696912f16ec0e12e8941 Mon Sep 17 00:00:00 2001 From: Davide Alberani Date: Sat, 4 Apr 2015 13:01:33 +0200 Subject: [PATCH] move registered persons into events collection --- angular_app/js/controllers.js | 8 ++--- angular_app/js/services.js | 2 ++ angular_app/person-detail.html | 12 +++---- backend.py | 30 +++++++++++++---- eventman_server.py | 61 +++++++++++++++++++++++++--------- 5 files changed, 81 insertions(+), 32 deletions(-) diff --git a/angular_app/js/controllers.js b/angular_app/js/controllers.js index 48c9018..e4271b7 100644 --- a/angular_app/js/controllers.js +++ b/angular_app/js/controllers.js @@ -74,13 +74,13 @@ eventManControllers.controller('PersonsListCtrl', ['$scope', 'Person', ); -eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$routeParams', 'Person', 'Action', - function ($scope, $routeParams, Person, Action) { +eventManControllers.controller('PersonDetailsCtrl', ['$scope', '$routeParams', 'Person', + function ($scope, $routeParams, Person) { if ($routeParams.id) { $scope.person = Person.get($routeParams); - Action.get({person_id: $routeParams.id}, function(data) { + /* Action.get({person_id: $routeParams.id}, function(data) { $scope.actions = angular.fromJson(data).actions; - }); + }); */ } // store a new Person or update an existing one $scope.save = function() { diff --git a/angular_app/js/services.js b/angular_app/js/services.js index 4d3358f..b6ff1be 100644 --- a/angular_app/js/services.js +++ b/angular_app/js/services.js @@ -3,11 +3,13 @@ /* Services that are used to interact with the backend. */ var eventManServices = angular.module('eventManServices', ['ngResource']); +/* eventManServices.factory('Action', ['$resource', function($resource) { return $resource('actions'); }] ); +*/ eventManServices.factory('Event', ['$resource', function($resource) { diff --git a/angular_app/person-detail.html b/angular_app/person-detail.html index c791b28..3fec012 100644 --- a/angular_app/person-detail.html +++ b/angular_app/person-detail.html @@ -20,18 +20,18 @@
-
Actions
+
Events
- - + + - - - + + +
ActionEvent IDEventAttended
{{action.action}}{{action.event_id}}
{{event.title}}action.event_id
diff --git a/backend.py b/backend.py index 78965d3..5eb4867 100644 --- a/backend.py +++ b/backend.py @@ -132,12 +132,12 @@ class EventManDB(object): ret = db[collection].update(data, {'$set': data}, upsert=True) return ret['updatedExisting'] - def update(self, collection, _id, data): + def update(self, collection, _id_or_query, data, operator='$set'): """Update an existing document. :param collection: update a document in this collection :type collection: str - :param _id: unique ID of the document to be updatd + :param _id: unique ID of the document to be updated :type _id: str or :class:`~bson.objectid.ObjectId` :param data: the updated information to store :type data: dict @@ -147,12 +147,29 @@ class EventManDB(object): """ db = self.connect() data = data or {} + if _id_or_query is None: + _id_or_query = {'_id': None} + 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)} if '_id' in data: del data['_id'] - db[collection].update({'_id': self.toID(_id)}, {'$set': data}) - return self.get(collection, _id) + res = db[collection].find_and_modify(query=_id_or_query, + update={operator: data}, full_response=True, new=True,upsert=True) + lastErrorObject = res.get('lastErrorObject') or {} + return lastErrorObject.get('updatedExisting', False), res.get('value') or {} - def merge(self, collection, data, searchBy): + def buildSearchPattern(self, data, searchBy): + _or = [] + for searchPattern in searchBy: + try: + _or.append(dict([(k, data[k]) for k in searchPattern])) + except KeyError: + continue + return _or + + def merge(self, collection, data, searchBy, operator='$set'): """Update an existing document. :param collection: update a document in this collection @@ -172,7 +189,8 @@ class EventManDB(object): continue if not _or: return False, None - ret = db[collection].update({'$or': _or}, {'$set': data}, upsert=True) + # Two-steps merge/find to count the number of merged documents + ret = db[collection].update({'$or': _or}, {operator: data}, upsert=True) _id = ret.get('upserted') if _id is None: newDoc = db[collection].find_one(data) diff --git a/eventman_server.py b/eventman_server.py index 260a6b6..078f9b1 100755 --- a/eventman_server.py +++ b/eventman_server.py @@ -80,11 +80,9 @@ class CollectionHandler(BaseHandler): def post(self, id_=None, **kwargs): data = escape.json_decode(self.request.body or {}) if id_ is None: - # insert a new document newData = self.db.add(self.collection, data) else: - # update an existing document - newData = self.db.update(self.collection, id_, data) + merged, newData = self.db.update(self.collection, id_, data) self.write(newData) # PUT (update an existing document) is handled by the POST (create a new document) method @@ -98,19 +96,36 @@ class CollectionHandler(BaseHandler): class PersonsHandler(CollectionHandler): """Handle requests for Persons.""" collection = 'persons' + object_id = 'person_id' + connect_to = 'events' + connect_id = 'event_id' - def handle_events(self, _id, **kwds): - return {'events': []} + def _handle_actions(self, id_, action=None, **kwds): + print id_, kwds + self.request.arguments + query = {self.object_id: self.db.toID(id_)} + if action: + query['action'] = action + actions = self.db.query('actions', query) + + return {self.connect_to: results} + + def handle_registered(self, id_, **kwds): + return self._handle_actions(id_, 'registered', **kwds) class EventsHandler(CollectionHandler): """Handle requests for Events.""" collection = 'events' + object_id = 'event_id' + connect_to = 'persons' + connect_id = 'person_id' class ActionsHandler(CollectionHandler): """Handle requests for Actions.""" collection = 'actions' + object_id = 'action_id' def get(self, *args, **kwargs): params = self.request.arguments or {} @@ -131,14 +146,18 @@ class EbCSVImportPersonsHandler(BaseHandler): 'Cognome acquirente': 'surname', 'Nome acquirente': 'name', 'E-mail acquirente': 'email', - 'Cognome': 'original_surname', - 'Nome': 'original_name', - 'E-mail': 'original_email', + 'Cognome': 'surname', + 'Nome': 'name', + 'E-mail': 'email', 'Tipologia biglietto': 'ticket_kind', 'Data partecipazione': 'attending_datetime', 'Data check-in': 'checkin_datetime', 'Ordine n.': 'order_nr', + 'ID ordine': 'order_nr', + 'Prefisso (Sig., Sig.ra, ecc.)': 'name_title', } + keepPersonData = ('name', 'surname', 'email') + @gen.coroutine def post(self, **kwargs): targetEvent = None @@ -146,7 +165,7 @@ class EbCSVImportPersonsHandler(BaseHandler): targetEvent = self.get_body_argument('targetEvent') except: pass - reply = dict(total=0, valid=0, merged=0) + reply = dict(total=0, valid=0, merged=0, new_in_event=0) for fieldname, contents in self.request.files.iteritems(): for content in contents: filename = content['filename'] @@ -154,17 +173,27 @@ class EbCSVImportPersonsHandler(BaseHandler): reply['total'] += parseStats['total'] reply['valid'] += parseStats['valid'] for person in persons: - merged, _id = self.db.merge('persons', person, - searchBy=[('email',), ('name', 'surname')]) + person_data = dict([(k, person[k]) for k in self.keepPersonData + if k in person]) + merged, person = self.db.update('persons', + [('email',), ('name', 'surname')], + person_data) if merged: reply['merged'] += 1 - if targetEvent and _id: + if targetEvent and person: + event_id = self.db.toID(targetEvent) + person_id = self.db.toID(person['_id']) registered_data = { - 'event_id': self.db.toID(targetEvent), - 'person_id': self.db.toID(_id), - 'action': 'registered', + 'person_id': person_id, + 'attended': False, 'from_file': filename} - self.db.insertOne('actions', registered_data) + person.update(registered_data) + if not self.db.query('events', + {'_id': event_id, 'registered.person_id': person_id}): + self.db.update('events', {'_id': event_id}, + {'registered': person}, + operator='$addToSet') + reply['new_in_event'] += 1 self.write(reply)