Skip to content

Commit

Permalink
new results page
Browse files Browse the repository at this point in the history
  • Loading branch information
psawaya committed Apr 5, 2012
1 parent 4c133dc commit ad57a17
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 71 deletions.
31 changes: 22 additions & 9 deletions PlacePulse/db.py
Expand Up @@ -6,6 +6,15 @@
from random import choice

class database(object):
#--------------------Results
def getResultsForStudy(self,studyName):
try:
return self.results.find_one({
'question_shortid': studyName
})
except:
return None

#--------------------Studies
def getStudy(self,study_id):
try:
Expand Down Expand Up @@ -74,9 +83,9 @@ def getNewCities(self,limit):
return None

#--------------------Locations
def getLocations(self,study_id):
def getLocations(self,study_id,limit=24):
try:
return self.locations.find({'study_id': study_id}).limit(24)
return self.locations.find({'study_id': study_id}).limit(limit)
except:
return None

Expand All @@ -99,18 +108,22 @@ def deleteLocation(self,location_id):
return True
except:
return None

@property
def votes(self):
return self.db.votes

def locations(self):
return self.db.locations

@property
def results(self):
return self.db.results

@property
def studies(self):
return self.db.studies

@property
def locations(self):
return self.db.locations
def votes(self):
return self.db.votes

@property
def db(self):
Expand Down
17 changes: 10 additions & 7 deletions PlacePulse/static/js/results.js
Expand Up @@ -11,7 +11,7 @@ $(document).ready(function() {
loadScript();
$.ajax({
'type': 'GET',
'url': '/results_data',
'url': '/top_results_data/' + STUDY_NAME,
'dataType': 'json',
'success': renderResults
});
Expand Down Expand Up @@ -57,6 +57,7 @@ function renderResults(resultsData) {
$('.questionName').html(resultsData.question);

var resultTemplate = _.template($('#rankItemTemplate').html());
var imageTemplate = _.template($('#rankedImageTemplate').html());

for (var city in resultsData.ranking) {
var cityItem = $(resultTemplate(resultsData.ranking[city]));
Expand All @@ -67,25 +68,27 @@ function renderResults(resultsData) {
function renderImgList(appendTo,coordsList) {
for (var item in coordsList) {
var imgCoords = coordsList[item].coords;
var newImg = $('<img>').attr('src',getSVURL(imgCoords[0],imgCoords[1]));
$(appendTo).append(newImg);
var newImg = $(imageTemplate(coordsList[item]));
$(appendTo).append(newImg);
newImg.get()[0].mapCoords = imgCoords;
}
}
renderImgList(cityItem.find('.topRanked'),cityRanking.top);
renderImgList(cityItem.find('.bottomRanked'),cityRanking.bottom);
}

$('.rankItems').on('click','img',null,function() {
$('.rankItems').on('click','.rankedImage',null,function() {
var gmapsCoords = new google.maps.LatLng(this.mapCoords[0],this.mapCoords[1]);
map.panTo(gmapsCoords);
marker.setPosition(gmapsCoords);
marker.setAnimation(google.maps.Animation.BOUNCE);
});
}

function getSVURL(lat,lng) {
var imageWidth = $('.rankItems').width()/3 - 50;
var imageHeight = Math.round(imageWidth*0.75);
function getSVURL(lat,lng,imageWidth,imageHeight) {
if (!imageWidth)
imageWidth = $('.rankItems').width()/3 - 50;
if (!imageHeight)
imageHeight = Math.round(imageWidth*0.75);
return "http://maps.googleapis.com/maps/api/streetview?size=" + imageWidth + "x" + imageHeight + "&location=" + lat + "," + lng + "&sensor=false";
}
102 changes: 56 additions & 46 deletions PlacePulse/study.py
Expand Up @@ -173,51 +173,61 @@ def get_location(location_id):
return "<img src='http://maps.googleapis.com/maps/api/streetview?size=404x296&location=" + lat + "," + lng + "&sensor=false'/>"

#--------------------Results
@study.route('/results/<studyName>/',methods = ['GET'])
def showSpecificBigStudyResults(studyName):
return showBigStudyResults(studyName)

@study.route('/results/',methods = ['GET'])
def showBigStudyResults():
return auto_template('results.html')
def showBigStudyResults(studyName='unique'):
# 'unique' is the default study
studyQuestions = [
("Which place looks more unique?","unique"),
("Which place looks safer?","safer"),
("Which place looks more upper class?","upper_class"),
("Which place looks more lively?","lively"),
("Which place looks more modern?","modern"),
("Which place looks more central?","central"),
("Which place looks more groomed?","groomed")
]
return auto_template('results.html', study_name=studyName, study_questions=studyQuestions)

@study.route('/results_data/<studyName>/',methods = ['GET'])
def getResultsData(studyName):
return jsonifyResponse(Database.getResultsForStudy(studyName))

@study.route('/top_results_data/<studyName>/',methods = ['GET'])
def getTopResultsData(studyName):
studyResults = Database.getResultsForStudy(studyName)
# To save space, show only the top and bottom 3 for each city
for city in studyResults['ranking']:
city['top'] = city['places'][0:3]
city['bottom'] = city['places'][-3:]
del city['places']
return jsonifyResponse(studyResults)

@study.route('/results_data/',methods = ['GET'])
def getResultsData():
safestCityResults = {
'question': "Which place looks more unique?",
'ranking': [
{
'city_name': 'Sao Paulo',
'top': [{'coords': [-23.547865000000002, -46.675600000000031], 'type': 'streetview'}, {'coords': [-23.541809000000001, -46.642515000000003], 'type': 'streetview'}, {'coords': [-23.530771000000001, -46.651857000000007]}],
'bottom': [{'coords': [-23.600961999999999, -46.654426999999998], 'type': 'streetview'}, {'coords': [-23.566029, -46.613223000000005], 'type': 'streetview'}, {'coords': [-23.588011000000002, -46.668845000000033], 'type': 'streetview'}]
},
{
'city_name': 'New York City',
'top': [{'coords': [40.766919999999999, -73.898903000000018], 'type': 'streetview'}, {'coords': [40.799993999999998, -73.913370999999984], 'type': 'streetview'}, {'coords': [40.737164999999997, -73.885324999999966], 'type': 'streetview'}],
'bottom': [{'coords': [40.74297, -73.891733999999985], 'type': 'streetview'}, {'coords': [40.711815000000001, -73.807912999999985], 'type': 'streetview'}, {'coords': [40.687119000000003, -73.949285000000032], 'type': 'streetview'}]
},
{
'city_name': 'Los Angeles',
'top': [{'coords': [33.997357999999998, -118.28591], 'type': 'streetview'}, {'coords': [33.991506000000001, -118.39314000000002], 'type': 'streetview'}, {'coords': [34.019933999999999, -118.37815399999999], 'type': 'streetview'}],
'bottom': [{'coords': [33.939588999999998, -118.348253], 'type': 'streetview'}, {'coords': [33.983154999999996, -118.33376900000002], 'type': 'streetview'}, {'coords': [34.017209999999999, -118.27480800000001], 'type': 'streetview'}]
},
{
'city_name': 'Tokyo',
'top': [{'coords': [35.680777999999997, 139.71636599999999], 'type': 'streetview'}, {'coords': [35.63702, 139.74308799999994], 'type': 'streetview'}, {'coords': [35.676063999999997, 139.65205000000003], 'type': 'streetview'}],
'bottom': [{'coords': [35.703251999999999, 139.75068299999998], 'type': 'streetview'}, {'coords': [35.706812999999997, 139.77918699999998], 'type': 'streetview'}, {'coords': [35.727221999999998, 139.86986000000002], 'type': 'streetview'}]
},
{
'city_name': 'Mexico City',
'top': [{'coords': [19.424503999999999, -99.13759600000003], 'type': 'streetview'}, {'coords': [19.457988, -99.116128000000003], 'type': 'streetview'}, {'coords': [19.445329000000001, -99.147404999999992], 'type': 'streetview'}],
'bottom': [{'coords': [19.458265999999998, -99.133131999999989], 'type': 'streetview'}, {'coords': [19.414881000000001, -99.139445000000023], 'type': 'streetview'}, {'coords': [19.401679000000001, -99.021538000000021], 'type': 'streetview'}]
}
]
}
return jsonifyResponse(safestCityResults)


@study.route('/results/<study_id>/',methods = ['GET'])
def showData(study_id):
L=""
for x in Database.votes.find({'study_id':study_id}):
leftStuff = re.sub("[^,0123456789.-]",'',str(Database.getPlace(x['left'])['loc']))
rightStuff = re.sub("[^,0123456789.-]",'',str(Database.getPlace(x['right'])['loc']))
L+=str(leftStuff)+","+str(rightStuff)+","+str(x['choice'])+","
L=L[:-1]
return auto_template('results.html',study_id=study_id, L=L)
@study.route('/rankings/<cityNameId>/',methods = ['GET'])
def getCityResults(cityNameId):
return auto_template('city_results.html',city_name_id=cityNameId)

@study.route('/rankings_data/<cityNameId>/',methods = ['GET'])
def getCityResultsData(cityNameId):
mainStudyResults = [i for i in Database.results.find({'study_type': 'main_study'})]
cityResults = []
for results in mainStudyResults:
resultsForStudy = [i for i in results['ranking'] if i['city_name_id'] == cityNameId]
cityResults.append({
'question': results['question'],
'question_shortid': results['question_shortid'],
'ranking': resultsForStudy
})
return jsonifyResponse(cityResults)

# @study.route('/results/<study_id>/',methods = ['GET'])
# def showData(study_id):
# L=""
# for x in Database.votes.find({'study_id':study_id}):
# leftStuff = re.sub("[^,0123456789.-]",'',str(Database.getPlace(x['left'])['loc']))
# rightStuff = re.sub("[^,0123456789.-]",'',str(Database.getPlace(x['right'])['loc']))
# L+=str(leftStuff)+","+str(rightStuff)+","+str(x['choice'])+","
# L=L[:-1]
# return auto_template('results.html',study_id=study_id, L=L)
53 changes: 46 additions & 7 deletions PlacePulse/templates/results.html
Expand Up @@ -2,16 +2,42 @@

{% block header %}
<style>
.clear {
clear:both;
}
.rank {
font-weight:bold;
}
.rankings img {
padding:5px;
z-index:99;
}
.rankings img:hover {
cursor:pointer;
}
.rankedImage {
float:left;
width:230px;
height:173px;

margin:3px;

cursor:pointer;
}
.rankedImageStats {
visibility:hidden;
color:white;
/* float:left;*/
}
.rankedImage:hover .rankedImageStats {
visibility:visible;
opacity:0.7;
background-color:black;
position:absolute;
}
#results_map {
width: 300px;
height: 300px;

}
#results_map_container {
/*FIXME: position:fixed may not work in IE7&8, need testing.*/
Expand All @@ -24,6 +50,10 @@
<link href="/static/css/responsive.css" rel="stylesheet">
<link href="/static/css/main.css" rel="stylesheet">

<script>
var STUDY_NAME = "{{ study_name }}";
</script>

{% endblock %}

{% block nav %}
Expand All @@ -40,13 +70,24 @@

<script type="text/template" id="rankItemTemplate">
<div>
<h3><%= city_name %></h3>
<h2><a href="/rankings/<%= city_name_id %>"><%= city_name %></a></h2>
<div class="topRanked rankings">
<h4>Top:</h4>
</div>
<div class="clear"/>
<div class="bottomRanked rankings">
<h4>Bottom:</h4>
</div>
<div class="clear"/>
</div>
</script>

<script type="text/template" id="rankedImageTemplate">
<div class="rankedImage" style="background-image: url(<% print(getSVURL(coords[0],coords[1],230,173)); %>)">
<span class="rankedImageStats">
<span>City rank: <span class="rank cityRank"><%= city_rank %></span></span>
<span>Site rank: <span class="rank siteRank"><%= site_rank %></span></span>
</span>
</div>
</script>
{% endblock %}
Expand All @@ -65,13 +106,11 @@ <h1 class="questionName">Dropdown</h1>
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="#">Which place looks safer?</a></li>
<li><a href="#">Which place looks more upper-class?</a></li>
{% for question in study_questions %}
<li><a href="/results/{{ question[1] }}">{{ question[0] }}</a></li>
{% endfor %}
</ul>
</li>
<!-- <h1 class="questionName">
</h1> -->
<div class="rankItems"></div>
</div>
</div>
Expand Down
22 changes: 20 additions & 2 deletions PlacePulse/util.py
Expand Up @@ -3,8 +3,11 @@
from PlacePulse import app

from flask import render_template,request,session,url_for
from pymongo.objectid import ObjectId

import json
import re
from unicodedata import normalize

class Buckets:
Unknown, Queue, Archive = range(3)
Expand All @@ -29,12 +32,27 @@ def getLoggedInUser():
return session.get('userObj')

def jsonifyResponse(obj):
resp = app.make_response(json.dumps(obj))
def default_handler(_obj):
if isinstance(_obj,ObjectId):
return str(_obj)
raise TypeError,"Unknown obj in JSON, %s, %s" % (type(_obj),_obj)
resp = app.make_response(json.dumps(obj,default=default_handler))
resp.mimetype = 'application/json'
return resp

def objifyPlace(place):
return {
'id' : str(place['_id']),
'loc' : place['loc']
}
}

# Public domain snippet from http://flask.pocoo.org/snippets/5/
_punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')
def slugify(text, delim=u'-'):
"""Generates an slightly worse ASCII-only slug."""
result = []
for word in _punct_re.split(text.lower()):
word = normalize('NFKD', unicode(word)).encode('ascii', 'ignore')
if word:
result.append(word)
return unicode(delim.join(result))

0 comments on commit ad57a17

Please sign in to comment.