Repository: fossasia/open-event-server

Issue:
Search functionality inconsistent
Seem to be getting server errors from time to time. Inconsistent. Especially with UTF-8 characters.


Discussion:

Resolving patch:
diff --git a/app/helpers/static.py b/app/helpers/static.py
--- a/app/helpers/static.py
+++ b/app/helpers/static.py
@@ -234,9 +234,9 @@
     'Alumni': 'Alumni.jpg',
     'Animal Welfare': 'AnimalWelfare.jpg',
     'Anime': 'Anime.jpg',
-    'Anime/Comics': 'Anime/Comics.jpg',
+    'Anime/Comics': 'Anime.jpg',
     'Auto': 'Auto.jpg',
-    'Auto, Boat & Air': 'Auto,Boat&Air.jpg',
+    'Auto, Boat & Air': 'AutoBoatAir.jpg',
     'Avatar': 'avatar.png',
     'Baby': 'Baby.jpg',
     'Ballet': 'Ballet.jpg',
@@ -245,28 +245,28 @@
     'Beauty': 'Beauty.jpg',
     'Beer': 'Beer.jpg',
     'Biotech': 'Biotech.jpg',
-    'Blues & Jazz': 'Blues&Jazz.jpg',
+    'Blues & Jazz': 'BluesJazz.jpg',
     'Boat': 'Boat.jpg',
     'Books': 'Books.jpg',
     'Bridal': 'Bridal.jpg',
     'Buddhism': 'Buddhism.jpg',
-    'Business & Professional': 'Business&Professional.jpg',
+    'Business & Professional': 'BusinessProfessional.jpg',
     'Canoeing': 'Canoeing.jpg',
     'Career': 'Career.jpg',
     'Channukah': 'Channukah.jpg',
-    'Charity & Causes': 'Charity&Causes.jpg',
-    'Children & Youth': 'Children&Youth.jpg',
+    'Charity & Causes': 'CharityCauses.jpg',
+    'Children & Youth': 'ChildrenYouth.jpg',
     'Christianity': 'Christianity.jpg',
     'Christmas': 'Christmas.jpg',
-    'City/Town': 'City/Town.jpg',
+    'City/Town': 'CityTown.jpg',
     'Classical': 'Classical.jpg',
     'Climbing': 'Climbing.jpg',
     'Comedy': 'Comedy.jpg',
     'Comics': 'Comics.jpg',
-    'Community & Culture': 'Community&Culture.jpg',
+    'Community & Culture': 'CommunityCulture.jpg',
     'Country': 'Country.jpg',
     'County': 'County.jpg',
-    'County/Municipal Government': 'County/MunicipalGovernment.jpg',
+    'County/Municipal Government': 'CountyMunicipalGovernment.jpg',
     'Craft': 'Craft.jpg',
     'Cultural': 'Cultural.jpg',
     'Cycling': 'Cycling.jpg',
@@ -276,40 +276,40 @@
     'Democratic Party': 'DemocraticParty.jpg',
     'Design': 'Design.jpg',
     'Disaster Relief': 'DisasterRelief.jpg',
-    'Drawing & Painting': 'Drawing&Painting.jpg',
-    'EDM / Electronic': 'EDM/Electronic.jpg',
+    'Drawing & Painting': 'DrawingPainting.jpg',
+    'EDM / Electronic': 'EDMElectronic.jpg',
     'Easter': 'Easter.jpg',
     'Eastern Religion': 'EasternReligion.jpg',
     'Education': 'Education.jpg',
     'Educators': 'Educators.jpg',
-    'Environment & Sustainability': 'Environment&Sustainability.jpg',
+    'Environment & Sustainability': 'EnvironmentSustainability.jpg',
     'Environment': 'Environment.jpg',
     'Exercise': 'Exercise.jpg',
     'Fall events': 'Fallevents.jpg',
-    'Family & Education': 'Family&Education.jpg',
-    'Fashion & Beauty': 'Fashion&Beauty.jpg',
+    'Family & Education': 'FamilyEducation.jpg',
+    'Fashion & Beauty': 'FashionBeauty.jpg',
     'Fashion': 'Fashion.jpg',
     'Federal Government': 'FederalGovernment.jpg',
-    'Fighting & Martial Arts': 'Fighting&MartialArts.jpg',
+    'Fighting & Martial Arts': 'FightingMartialArts.jpg',
     'Film': 'Film.jpg',
-    'Film, Media & Entertainment': 'Film,Media&Entertainment.jpg',
+    'Film, Media & Entertainment': 'FilmMediaEntertainment.jpg',
     'Finance': 'Finance.jpg',
     'Fine Art': 'FineArt.jpg',
     'Folk': 'Folk.jpg',
-    'Food & Drink': 'Food&Drink.jpg',
+    'Food & Drink': 'FoodDrink.jpg',
     'Food': 'Food.jpg',
     'Football': 'Football.jpg',
     'Gaming': 'Gaming.jpg',
     'Golf': 'Golf.jpg',
-    'Government & Politics': 'Government&Politics.jpg',
-    'Halloween/Haunt': 'Halloween/Haunt.jpg',
-    'Health & Wellness': 'Health&Wellness.jpg',
+    'Government & Politics': 'GovernmentPolitics.jpg',
+    'Halloween/Haunt': 'HalloweenHaunt.jpg',
+    'Health & Wellness': 'HealthWellness.jpg',
     'Healthcare': 'Healthcare.jpg',
     'Heritage': 'Heritage.jpg',
     'High Tech': 'HighTech.jpg',
     'Hiking': 'Hiking.jpg',
-    'Hip Hop / Rap': 'HipHop/Rap.jpg',
-    'Hobbies & Special Interest': 'Hobbies&SpecialInterest.jpg',
+    'Hip Hop / Rap': 'HipHopRap.jpg',
+    'Hobbies & Special Interest': 'HobbiesSpecialInterest.jpg',
     'Hockey': 'Hockey.jpg',
     'Home & Garden': 'Home&Garden.jpg',
     'Home & Lifestyle': 'Home&Lifestyle.jpg',
@@ -326,21 +326,23 @@
     'Latin': 'Latin.jpg',
     'Literary Arts': 'LiteraryArts.jpg',
     'Media': 'Media.jpg',
+    'Medical': 'Medical.jpg',
     'Medicine': 'Medicine.jpg',
     'Medieval': 'Medieval.jpg',
+    'Mental Health': 'MentalHealth.jpg',
     'Metal': 'Metal.jpg',
     'Mobile': 'Mobile.jpg',
     'Mormonism': 'Mormonism.jpg',
-    'Motorcycle/ATV': 'Motorcycle/ATV.jpg',
+    'Motorcycle/ATV': 'MotorcycleATV.jpg',
     'Motorsports': 'Motorsports.jpg',
     'Mountain Biking': 'MountainBiking.jpg',
     'Music': 'Music.jpg',
     'Musical': 'Musical.jpg',
-    'Mysticism and Occult': 'MysticismandOccult.jpg',
+    'Mysticism & Occult': 'MysticismOccult.jpg',
     'Nationality': 'Nationality.jpg',
     'New Age': 'NewAge.jpg',
     'New Years Eve': 'NewYearsEve.jpg',
-    'Non Profit & NGOs': 'NonProfit&NGOs.jpg',
+    'Non Profit & NGOs': 'NonProfitNGOs.jpg',
     'Non-partisan': 'Non-partisan.jpg',
     'Obstacles': 'Obstacles.jpg',
     'Opera': 'Opera.jpg',
@@ -350,16 +352,17 @@
     'Parenting': 'Parenting.jpg',
     'Parents Association': 'ParentsAssociation.jpg',
     'Performing & Visual Arts': 'Performing&VisualArts.jpg',
+    'Personal Health': 'PersonalHealth.jpg',
     'Pets & Animals': 'Pets&Animals.jpg',
     'Photography': 'Photography.jpg',
     'Pop': 'Pop.jpg',
     'Poverty': 'Poverty.jpg',
-    'R&B': 'R&B.jpg',
+    'R&B': 'RB.jpg',
     'Rafting': 'Rafting.jpg',
     'Real Estate': 'RealEstate.jpg',
     'Reggae': 'Reggae.jpg',
-    'Religion & Spirituality': 'Religion&Spirituality.jpg',
-    'Religious/Spiritual': 'Religious/Spiritual.jpg',
+    'Religion & Spirituality': 'ReligionSpirituality.jpg',
+    'Religious/Spiritual': 'ReligiousSpiritual.jpg',
     'Renaissance': 'Renaissance.jpg',
     'Republican Party': 'RepublicanParty.jpg',
     'Reunion': 'Reunion.jpg',
@@ -370,45 +373,23 @@
     'Sales & Marketing': 'Sales&Marketing.jpg',
     'Science & Technology': 'Science&Technology.jpg',
     'Science': 'Science.jpg',
-    'Seasonal & Holiday': 'Seasonal&Holiday.jpg',
+    'Seasonal & Holiday': 'SeasonalHoliday.jpg',
     'Sikhism': 'Sikhism.jpg',
     'Snow Sports': 'SnowSports.jpg',
     'Soccer': 'Soccer.jpg',
     'Social Media': 'SocialMedia.jpg',
+    'Spa': 'Spa.jpg',
     'Spirits': 'Spirits.jpg',
-    'Sports & Fitness': 'Sports&Fitness.jpg',
+    'Sports & Fitness': 'SportsFitness.jpg',
     'St Patricks Day': 'StPatricksDay.jpg',
-    'Startups & Small Business': 'Startups&SmallBusiness.jpg',
+    'Startups & Small Business': 'StartupsSmallBusiness.jpg',
     'State Government': 'StateGovernment.jpg',
     'State': 'State.jpg',
-    'Swimming & Water Sports': 'Swimming&WaterSports.jpg',
+    'Swimming & Water Sports': 'SwimmingWaterSports.jpg',
     'TV': 'TV.jpg',
     'Tennis': 'Tennis.jpg',
     'Thanksgiving': 'Thanksgiving.jpg',
     'Theatre': 'Theatre.jpg',
-    'Top 40': 'Top40.jpg',
-    'Travel & Outdoor': 'Travel&Outdoor.jpg',
+    'Travel & Outdoor': 'TravelOutdoor.jpg',
     'Travel': 'Travel.jpg',
-    'Dance': 'Dance.jpg',
-    'Democratic Party': 'DemocraticParty.jpg',
-    'Avatar': 'avatar.png',
-    'City/Town': 'City/Town.jpg',
-    'Home & Lifestyle': 'Home&Lifestyle.jpg',
-    'New Age': 'NewAge.jpg',
-    'Food': 'Food.jpg',
-    'Children & Youth': 'Children&Youth.jpg',
-    'Design': 'Design.jpg',
-    'Folk': 'Folk.jpg',
-    'Hockey': 'Hockey.jpg',
-    'Real Estate': 'RealEstate.jpg',
-    'Drawing & Painting': 'Drawing&Painting.jpg',
-    'St Patricks Day': 'StPatricksDay.jpg',
-    'Community & Culture': 'Community&Culture.jpg',
-    'Channukah': 'Channukah.jpg',
-    'Film': 'Film.jpg',
-    'Islam': 'Islam.jpg',
-    'Medical': 'Medical.jpg',
-    'Mental Health': 'MentalHealth.jpg',
-    'Personal Health': 'PersonalHealth.jpg',
-    'Spa': 'Spa.jpg',
 }
diff --git a/app/views/public/explore.py b/app/views/public/explore.py
--- a/app/views/public/explore.py
+++ b/app/views/public/explore.py
@@ -1,14 +1,19 @@
+import json
+
+import requests
 from flask import Blueprint
 from flask import render_template
 from flask import request, redirect, url_for, jsonify
 from flask.ext.restplus import abort
 from flask_restplus import marshal
+from requests import ConnectionError
 
-from app.api.events import EVENT
+from app.api.events import EVENT, EVENT_PAGINATED
 from app.api.helpers.helpers import get_paginated_list, get_object_list
 from app.helpers.data import DataGetter
 from app.helpers.flask_helpers import deslugify
 from app.helpers.helpers import get_date_range
+from app.helpers.static import EVENT_TOPICS
 from app.models.event import Event
 
 RESULTS_PER_PAGE = 10
@@ -43,6 +48,33 @@ def erase_from_dict(d, k):
             d.pop(k)
 
 
+def clean_dict(d):
+    d = dict(d)
+    return dict((k, v) for k, v in d.iteritems() if v)
+
+
+def get_coordinates(location_name):
+
+    location = {
+        'lat': 0.0,
+        'lng': 0.0
+    }
+
+    url = 'https://maps.googleapis.com/maps/api/geocode/json'
+    params = {'address': location_name}
+    response = dict()
+
+    try:
+        response = requests.get(url, params).json()
+    except ConnectionError:
+        response['status'] = u'Error'
+
+    if response['status'] == u'OK':
+        location = response['results'][0]['geometry']['location']
+
+    return location
+
+
 explore = Blueprint('explore', __name__, url_prefix='/explore')
 
 
@@ -59,7 +91,7 @@ def locations_autocomplete():
 
 @explore.route('/autocomplete/categories.json', methods=('GET', 'POST'))
 def categories_autocomplete():
-    categories = CATEGORIES.keys()
+    categories = EVENT_TOPICS.keys()
     return jsonify([{'value': category, 'type': 'category'} for category in categories])
 
 
@@ -76,12 +108,7 @@ def explore_view(location):
     placeholder_images = DataGetter.get_event_default_images()
     custom_placeholder = DataGetter.get_custom_placeholders()
     location = deslugify(location)
-    current_page = request.args.get('page')
     query = request.args.get('query', '')
-    if not current_page:
-        current_page = 1
-    else:
-        current_page = int(current_page)
 
     filtering = {'privacy': 'public', 'state': 'Published'}
     start, end = None, None
@@ -93,7 +120,7 @@ def explore_view(location):
 
     if day_filter:
         start, end = get_date_range(day_filter)
-    if location:
+    if location and location != 'world':
         filtering['__event_search_location'] = location
     if word:
         filtering['__event_contains'] = word
@@ -107,55 +134,22 @@ def explore_view(location):
         filtering['__event_start_time_gt'] = start
     if end:
         filtering['__event_end_time_lt'] = end
-    filters = request.args.items()
-    erase_from_dict(filters, 'page')
-    results = get_paginated(**filtering)
-
-    return render_template('gentelella/guest/search/results.html',
-                           results=results,
-                           location=location,
-                           filters=filters,
-                           current_page=current_page,
-                           placeholder_images=placeholder_images,
-                           custom_placeholder=custom_placeholder,
-                           categories=CATEGORIES, query=query)
-
-
-CATEGORIES = {'Auto, Boat & Air': ['Air', 'Auto', 'Boat', 'Motorcycle/ATV', 'Other'],
-              'Business & Professional':
-                  ['Career', 'Design', 'Educators', 'Environment &amp; Sustainability', 'Finance', 'Media',
-                   'Non Profit &amp; NGOs', 'Other', 'Real Estate', 'Sales &amp; Marketing',
-                   'Startups &amp; Small Business'],
-              'Charity & Causes': ['Animal Welfare', 'Disaster Relief', 'Education', 'Environment', 'Healthcare',
-                                   'Human Rights', 'International Aid', 'Other', 'Poverty'],
-              'Community & Culture': ['City/Town', 'County', 'Heritage', 'LGBT', 'Language', 'Medieval', 'Nationality',
-                                      'Other', 'Renaissance', 'State'],
-              'Family & Education': ['Alumni', 'Baby', 'Children &amp; Youth', 'Education', 'Other', 'Parenting',
-                                     'Parents Association', 'Reunion'],
-              'Fashion & Beauty': ['Accessories', 'Beauty', 'Bridal', 'Fashion', 'Other'],
-              'Film, Media & Entertainment': ['Adult', 'Anime', 'Comedy', 'Comics', 'Film', 'Gaming', 'Other', 'TV'],
-              'Food & Drink': ["Beer", "Food", "Other", "Spirits", "Wine"],
-              'Government & Politics': ["County/Municipal Government ", "Democratic Party", "Federal Government",
-                                        "Non-partisan", "Other", "Other Party", "Republican Party", "State Government"],
-              'Health & Wellness': ["Medical", "Mental health", "Other", "Personal health", "Spa", "Yoga"],
-              'Hobbies & Special Interest': ["Adult", "Anime/Comics", "Books", "DIY", "Drawing & Painting",
-                                             "Gaming", "Knitting", "Other", "Photography"],
-              'Home & Lifestyle': ["Dating", "Home & Garden", "Other", "Pets & Animals"],
-              'Music': ["Alternative", "Blues & Jazz", "Classical", "Country", "Cultural", "EDM / Electronic",
-                        "Folk", "Hip Hop / Rap", "Indie", "Latin", "Metal", "Opera", "Other", "Pop", "R&B", "Reggae",
-                        "Religious/Spiritual", "Rock", "Top 40"],
-              'Other': [],
-              'Performing & Visual Arts': ["Ballet", "Comedy", "Craft", "Dance", "Fine Art", "Literary Arts", "Musical",
-                                           "Opera", "Orchestra", "Other", "Theatre"],
-              'Religion & Spirituality': ["Buddhism", "Christianity", "Eastern Religion", "Islam", "Judaism",
-                                          "Mormonism", "Mysticism and Occult", "New Age", "Other", "Sikhism"],
-              'Science & Technology': ["Biotech", "High Tech", "Medicine", "Mobile", "Other", "Robotics",
-                                       "Science", "Social Media"],
-              'Seasonal & Holiday': ["Channukah", "Christmas", "Easter", "Fall events", "Halloween/Haunt",
-                                     "Independence Day", "New Years Eve", "Other", "St Patricks Day", "Thanksgiving"],
-              'Sports & Fitness': ["Baseball", "Basketball", "Cycling", "Exercise", "Fighting & Martial Arts",
-                                   "Football", "Golf", "Hockey", "Motorsports", "Mountain Biking", "Obstacles",
-                                   "Other", "Rugby", "Running", "Snow Sports", "Soccer", "Swimming & Water Sports",
-                                   "Tennis", "Volleyball", "Walking", "Yoga"],
-              'Travel & Outdoor': ["Canoeing", "Climbing", "Hiking", "Kayaking", "Other", "Rafting", "Travel"]
-              }
+
+    results = marshal(get_paginated(**filtering), EVENT_PAGINATED)
+    filters = clean_dict(request.args.items())
+
+    custom_placeholder_serializable = {}
+    for custom_placeholder_item in custom_placeholder:
+        custom_placeholder_serializable[custom_placeholder_item.name] = custom_placeholder_item.thumbnail
+
+    return render_template('gentelella/guest/explore/results.html',
+                           results=json.dumps(results['results']),
+                           location=location if location != 'world' else '',
+                           position=json.dumps(get_coordinates(location)),
+                           count=results['count'],
+                           query_args=json.dumps(filters),
+                           placeholder_images=json.dumps(placeholder_images),
+                           custom_placeholder=json.dumps(custom_placeholder_serializable),
+                           categories=EVENT_TOPICS,
+                           results_per_page=RESULTS_PER_PAGE,
+                           query=query)


Test patch: