Repository: fossasia/open-event-server

Issue:
Add pagination to search results
#846



Discussion:
@rafalkowalski I'll take this up


Resolving patch:
diff --git a/open_event/__init__.py b/open_event/__init__.py
--- a/open_event/__init__.py
+++ b/open_event/__init__.py
@@ -22,7 +22,8 @@
 from icalendar import Calendar, Event
 import humanize
 import sqlalchemy as sa
-from markupsafe import Markup
+from urllib import urlencode
+from urlparse import parse_qs, urlsplit, urlunsplit
 
 from open_event.helpers.flask_helpers import SilentUndefined
 from open_event.helpers.helpers import string_empty
@@ -144,6 +145,22 @@ def pretty_name_filter(s):
 def humanize_filter(time):
     return arrow.get(time).humanize()
 
+@app.context_processor
+def pagination_helpers():
+    def set_query_parameter(param_name, param_value, url=request.url):
+        """Given a URL, set or replace a query parameter and return the
+        modified URL.
+        """
+        scheme, netloc, path, query_string, fragment = urlsplit(url)
+        query_params = parse_qs(query_string)
+
+        query_params[param_name] = [param_value]
+        new_query_string = urlencode(query_params, doseq=True)
+
+        return urlunsplit((scheme, netloc, path, new_query_string, fragment))
+
+    return dict(set_query_parameter=set_query_parameter)
+
 @app.context_processor
 def versioning_manager():
     def count_versions(model_object):
diff --git a/open_event/views/public/browse.py b/open_event/views/public/browse.py
--- a/open_event/views/public/browse.py
+++ b/open_event/views/public/browse.py
@@ -1,22 +1,65 @@
+from flask.ext.restplus import abort
 from flask_admin import BaseView, expose
-from ...helpers.data_getter import DataGetter
+
+from open_event.api.helpers.helpers import get_paginated_list
+from open_event.models.event import Event
 from flask import request
-import requests
-from urlparse import urlparse
 from flask_restplus import marshal
 from open_event.api.events import DAO as EventDAO, EVENT
 
+RESULTS_PER_PAGE = 2
+
+def get_paginated(**kwargs):
+
+    current_page = request.args.get('page')
+    if current_page:
+        current_page = int(current_page) - 1
+        if current_page < 0:
+            abort(404)
+    else:
+        current_page = 0
+
+    try:
+        return get_paginated_list(Event, request.path, {
+            'start': (current_page * RESULTS_PER_PAGE) + 1,
+            'limit': RESULTS_PER_PAGE,
+        }, **kwargs)
+    except:
+        return {
+            'start': 0,
+            'count': 0,
+            'limit': RESULTS_PER_PAGE,
+            'results': []
+        }
+
+def erase_from_dict(d, k):
+    if isinstance(d, dict):
+        if k in d.keys():
+            d.pop(k)
+            print(d)
 
 class BrowseView(BaseView):
     @expose('/', methods=('GET', 'POST'))
     def browse(self, location):
-        results = DataGetter.get_all_events()
-        return self.render('/gentelella/guest/search/results.html', results=results, location=location)
+        current_page = request.args.get('page')
+        if not current_page:
+            current_page = 1
+        else:
+            current_page = int(current_page)
+        results = get_paginated(privacy='public', state='Published')
+        return self.render('/gentelella/guest/search/results.html', results=results, location=location,
+                           current_page=current_page)
 
     @expose('/s', methods=('GET', 'POST'))
     def browses(self, location):
-        results = marshal(EventDAO.list(location_name=location, privacy='public', state='Published'), EVENT)
+        current_page = request.args.get('page')
+        if not current_page:
+            current_page = 1
+        else:
+            current_page = int(current_page)
+        results = get_paginated(location_name=location, privacy='public', state='Published')
         filters = request.args.items()
+        erase_from_dict(filters, 'page')
         if request.method == "POST":
             word = request.form['word']
             event_type = request.args.get('event_type', '')
@@ -29,11 +72,15 @@ def browses(self, location):
                                   type=event_type),
                     EVENT)
             if location and word:
-                results = marshal(EventDAO.list(location_name=location, __event_contains=word, privacy='public', state='Published'), EVENT)
+                results = get_paginated(location_name=location, __event_contains=word, privacy='public', state='Published')
             elif location:
-                results = marshal(EventDAO.list(location_name=location, privacy='public', state='Published'), EVENT)
+                results = get_paginated(location_name=location, privacy='public', state='Published')
             elif word:
-                results = marshal(EventDAO.list(__event_contains=word, privacy='public', state='Published'), EVENT)
-            return self.render('/gentelella/guest/search/results.html', results=results, location=location, filters=filters)
-        return self.render('/gentelella/guest/search/results.html', results=results, location=location, filters=filters)
+                results = get_paginated(__event_contains=word, privacy='public', state='Published')
+
+        return self.render('/gentelella/guest/search/results.html',
+                           results=results,
+                           location=location,
+                           filters=filters,
+                           current_page=current_page)
 


Test patch: