Repository: fossasia/open-event-server

Issue:
Please add possibility to get events from locations and filter it by phase
#846

location='Berlin'&phase='Python'

TODO
Filtering
- [x] Location
- [x] Phase
- [x] state
- [x] start_time
- [x] end_time
- [x] privacy
- [x] type
- [x] topic

above example should returns all events from Berlin which have Python word in title or description



Discussion:
Filter by location has been added. See https://github.com/fossasia/open-event-orga-server/pull/964
I will add filter by phrase. 
You can see and play with available options here - http://open-event.herokuapp.com/api/v2/#!/events/get_event_list

@aviaryan how can i filter only events which are published?

No, not now but I will add filtering for `state` now that you mention it. 

@aviaryan I've added above todo list what i need

@rafalkowalski Can you please give example of queries you will need from 'start_time' and 'end_time' ? 

@aviaryan for example i need to display current published events not past events, so i need to filter it by date

@rafalkowalski Ok. I will add filter by start_time and end_time . In the meanwhile, can you review #1060, I have added all other options in it. 
Adding start_time and end_time may take some time. 


Resolving patch:
diff --git a/open_event/api/events.py b/open_event/api/events.py
--- a/open_event/api/events.py
+++ b/open_event/api/events.py
@@ -149,7 +149,11 @@ def update(self, event_id, data):
     },
     'topic': {
         'type': str
-    }
+    },
+    'start_time_gt': {},
+    'start_time_lt': {},
+    'end_time_gt': {},
+    'end_time_lt': {}
 }
 
 # DEFINE RESOURCES
@@ -166,6 +170,10 @@ class EventResource():
     event_parser.add_argument('privacy', type=str)
     event_parser.add_argument('type', type=str)
     event_parser.add_argument('topic', type=str)
+    event_parser.add_argument('start_time_gt', dest='__event_start_time_gt')
+    event_parser.add_argument('start_time_lt', dest='__event_start_time_lt')
+    event_parser.add_argument('end_time_gt', dest='__event_end_time_gt')
+    event_parser.add_argument('end_time_lt', dest='__event_end_time_lt')
 
 
 @api.route('/<int:event_id>')
diff --git a/open_event/api/helpers/query_filters.py b/open_event/api/helpers/query_filters.py
--- a/open_event/api/helpers/query_filters.py
+++ b/open_event/api/helpers/query_filters.py
@@ -1,6 +1,7 @@
 from sqlalchemy import or_, func
 
 from open_event.models.event import Event
+from custom_fields import DateTime
 
 
 def extract_special_queries(queries):
@@ -40,11 +41,31 @@ def event_contains(value, query):
     return q
 
 
+def event_start_time_gt(value, query):
+    return query.filter(Event.start_time >= DateTime().from_str(value))
+
+
+def event_start_time_lt(value, query):
+    return query.filter(Event.start_time <= DateTime().from_str(value))
+
+
+def event_end_time_gt(value, query):
+    return query.filter(Event.end_time >= DateTime().from_str(value))
+
+
+def event_end_time_lt(value, query):
+    return query.filter(Event.end_time <= DateTime().from_str(value))
+
+
 #######
 # ADD CUSTOM FILTERS TO LIST
 #######
 
 
 FILTERS_LIST = {
-    '__event_contains': event_contains
+    '__event_contains': event_contains,
+    '__event_start_time_gt': event_start_time_gt,
+    '__event_start_time_lt': event_start_time_lt,
+    '__event_end_time_gt': event_end_time_gt,
+    '__event_end_time_lt': event_end_time_lt,
 }


Test patch:
diff --git a/tests/api/test_get_list_queries.py b/tests/api/test_get_list_queries.py
--- a/tests/api/test_get_list_queries.py
+++ b/tests/api/test_get_list_queries.py
@@ -18,7 +18,7 @@ def setUp(self):
         self.app = Setup.create_app()
         with app.test_request_context():
             register(self.app, u'test@example.com', u'test')
-            create_event(creator_email='test@example.com')
+            create_event(name='TestEvent0', creator_email='test@example.com')
 
     def _post(self, path, data):
         """
@@ -45,6 +45,23 @@ def test_event_queries(self):
         resp = self.app.get(path + '?contains=test&state=r@nd0m')
         self.assertEqual(len(resp.data), 3)
 
+    def test_event_time_queries(self):
+        path = get_path()
+        # Event is of Apr 16
+        resp = self.app.get(path + '?end_time_lt=2015-12-31T23:59:59')
+        self.assertEqual(len(resp.data), 3, msg=resp.data)
+        resp = self.app.get(path + '?start_time_gt=2015-12-31T23:59:59')
+        self.assertIn('TestEvent0', resp.data)
+        # add one more event of May 16
+        resp = self._post(path, POST_EVENT_DATA)
+        self.assertEqual(resp.status_code, 201)
+        # test
+        resp = self.app.get(path + '?start_time_lt=2016-05-31T23:59:59')
+        self.assertEqual(len(json.loads(resp.data)), 2, msg=resp.data)
+        resp = self.app.get(path + '?end_time_gt=2016-05-01T00:00:00')
+        self.assertIn('"TestEvent"', resp.data)
+        self.assertNotIn('TestEvent0', resp.data)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/tests/api/utils.py b/tests/api/utils.py
--- a/tests/api/utils.py
+++ b/tests/api/utils.py
@@ -17,8 +17,8 @@ def create_event(name='TestEvent', creator_email=None):
     :param name Name of Event
     """
     event = Event(name=name,
-                  start_time=datetime(2013, 8, 4, 12, 30, 45),
-                  end_time=datetime(2016, 9, 4, 12, 30, 45))
+                  start_time=datetime(2016, 4, 8, 12, 30, 45),
+                  end_time=datetime(2016, 4, 9, 12, 30, 45))
     if creator_email:
         event.creator = User.query.filter_by(email=creator_email).first()
     save_to_db(event, 'Event saved')