A plethora of fixes to make this more usable on non-mobile devices; should gracefully degrade a bit better now... if it can't get any GPS coordinates, the user can enter an address and bypass that requirement, and we'll do a reverse lookup and get some GPS coordinates based on said address. Users can also now view the checkin history of other people - someone wanna implement friendships/privacy? We have an open source 4Square here. ;D
This commit is contained in:
parent
c17458cc8a
commit
d503e3fe08
11 changed files with 223 additions and 116 deletions
|
|
@ -23,7 +23,7 @@ class Location(models.Model):
|
||||||
name = models.CharField(max_length=200)
|
name = models.CharField(max_length=200)
|
||||||
street_address = models.CharField(max_length=200, blank=True)
|
street_address = models.CharField(max_length=200, blank=True)
|
||||||
category = models.ForeignKey(LocationCategory, blank=True, null=True)
|
category = models.ForeignKey(LocationCategory, blank=True, null=True)
|
||||||
geometry = models.PointField(srid=4326)
|
geometry = models.PointField(srid=4326, blank=True, null=True)
|
||||||
objects = models.GeoManager()
|
objects = models.GeoManager()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
@ -33,7 +33,6 @@ class Location(models.Model):
|
||||||
"""
|
"""
|
||||||
Tally up how many checkins this location had in the past day.
|
Tally up how many checkins this location had in the past day.
|
||||||
"""
|
"""
|
||||||
print self.checkin_set.filter(timestamp__gte = datetime.now() + timedelta(days=-1))
|
|
||||||
return self.checkin_set.filter(timestamp__gte = datetime.now() + timedelta(days=-1)).count()
|
return self.checkin_set.filter(timestamp__gte = datetime.now() + timedelta(days=-1)).count()
|
||||||
|
|
||||||
def address_for_geocode(self):
|
def address_for_geocode(self):
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,26 @@
|
||||||
|
import urllib2
|
||||||
|
from urllib2 import HTTPError
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Python 2.6 and up
|
||||||
|
import json as simplejson
|
||||||
|
except ImportError:
|
||||||
|
# This case gets rarer by the day, but if we need to, we can pull it from Django provided it's there.
|
||||||
|
from django.utils import simplejson
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from django.contrib.gis.geos import *
|
from django.contrib.gis.geos import *
|
||||||
from django.contrib.gis.measure import D
|
from django.contrib.gis.measure import D
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.auth.forms import UserCreationForm
|
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.shortcuts import render_to_response
|
from django.shortcuts import render_to_response
|
||||||
from django.utils import simplejson
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.template import RequestContext, Context
|
from django.template import RequestContext, Context
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.core.paginator import Paginator, InvalidPage, EmptyPage
|
from django.core.paginator import Paginator, InvalidPage, EmptyPage
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib.auth.forms import UserCreationForm
|
||||||
|
|
||||||
from drinkkit.redditors.models import LocationCategory, Location, Tip, Checkin
|
from drinkkit.redditors.models import LocationCategory, Location, Tip, Checkin
|
||||||
|
|
||||||
|
|
@ -153,16 +162,45 @@ def add_location(request):
|
||||||
fixed at some point. ;P
|
fixed at some point. ;P
|
||||||
"""
|
"""
|
||||||
if request.POST:
|
if request.POST:
|
||||||
if request.POST['location_name'] and request.POST['lat'] and request.POST['long']:
|
# Somewhat ugly, but meh.
|
||||||
|
if request.POST['location_name'] and (request.POST['street_address'] or (request.POST['lat'] and request.POST['long'])):
|
||||||
new_location = Location()
|
new_location = Location()
|
||||||
new_location.name = request.POST['location_name']
|
new_location.name = request.POST['location_name']
|
||||||
|
|
||||||
|
if request.POST['lat'] and request.POST['long']:
|
||||||
new_location.geometry = 'POINT(%s %s)' %(request.POST['lat'], request.POST['long'])
|
new_location.geometry = 'POINT(%s %s)' %(request.POST['lat'], request.POST['long'])
|
||||||
|
else:
|
||||||
|
# If we don't have a lat/long pair, we know they got here by providing a street address, so
|
||||||
|
# let's do some geocoding via Google APIs and find the lat/long ourselves.
|
||||||
|
#
|
||||||
|
# Note: We assume Washington, DC here because of the region this application is suited to. If
|
||||||
|
# you wanted to expand on this, you'd probably wanna get the region/IP-(lat/long) (which isn't as accurate)
|
||||||
|
# and use it to sandbox your results. This is a pretty hacky 5AM thing. ;P
|
||||||
|
fixed_address = request.POST['street_address'].replace(" ", "+")
|
||||||
|
api_url = "http://maps.googleapis.com/maps/api/geocode/json?&address=%s,Washington,DC&sensor=false" % fixed_address
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Download and parse the JSON response into native Python objects.
|
||||||
|
geocode_request = urllib2.Request(api_url)
|
||||||
|
geocoded_data = simplejson.load(urllib2.urlopen(geocode_request))
|
||||||
|
|
||||||
|
# Store latitude and longitude, for readability
|
||||||
|
for result in geocoded_data["results"]:
|
||||||
|
latitude = result["geometry"]["location"]["lat"]
|
||||||
|
longitude = result["geometry"]["location"]["lng"]
|
||||||
|
|
||||||
|
# Save our determined geometry coordinates
|
||||||
|
new_location.geometry = 'POINT(%s %s)' %(latitude, longitude)
|
||||||
|
except HTTPError:
|
||||||
|
# You're boned, Google's either blocking you or you done goofed. Ordinarily, you'd
|
||||||
|
# wanna handle errors properly here, but in my case I want a hard failure. YMMV.
|
||||||
|
pass
|
||||||
|
|
||||||
# If they've supplied a street address, sweet, use it.
|
# If they've supplied a street address, sweet, use it.
|
||||||
if request.POST['street_address']:
|
if request.POST['street_address']:
|
||||||
new_location.street_address = request.POST['street_address']
|
new_location.street_address = request.POST['street_address']
|
||||||
|
|
||||||
# If they set a location, let's record it... (5AM code)
|
# If they set a location type/category, let's record it... (5AM code)
|
||||||
if request.POST['location_type']:
|
if request.POST['location_type']:
|
||||||
try:
|
try:
|
||||||
category = LocationCategory.objects.get(id = request.POST['location_type'])
|
category = LocationCategory.objects.get(id = request.POST['location_type'])
|
||||||
|
|
@ -174,7 +212,7 @@ def add_location(request):
|
||||||
return HttpResponseRedirect('/locations/%s/' % str(new_location.id))
|
return HttpResponseRedirect('/locations/%s/' % str(new_location.id))
|
||||||
else:
|
else:
|
||||||
if not request.POST['lat'] or not request.POST['lat']:
|
if not request.POST['lat'] or not request.POST['lat']:
|
||||||
errmsg = "We weren't able to get coordinates for where you are right now. Does your phone or device have GPS?"
|
errmsg = "We weren't able to get coordinates for where you are right now. Does your phone or device have GPS? If not, specify an address and we'll use that instead!"
|
||||||
if not request.POST['location_name']:
|
if not request.POST['location_name']:
|
||||||
errmsg = "You didn't even bother to enter a name for this location. Wtf?"
|
errmsg = "You didn't even bother to enter a name for this location. Wtf?"
|
||||||
return render_to_response('locations/add.html',
|
return render_to_response('locations/add.html',
|
||||||
|
|
@ -235,8 +273,17 @@ def add_tip(request, location_id):
|
||||||
else:
|
else:
|
||||||
return HttpResponse(status=404)
|
return HttpResponse(status=404)
|
||||||
|
|
||||||
def find_redditors(request):
|
def view_redditor(request, redditor_name):
|
||||||
"""
|
"""
|
||||||
Handles locating all Redditors in a given area who recently checked in.
|
View a Redditor "profile" - right now, all we do is show their checkin
|
||||||
|
history (where they've been). Stalking is fun, right?
|
||||||
|
|
||||||
|
...right?
|
||||||
"""
|
"""
|
||||||
pass
|
try:
|
||||||
|
redditor = User.objects.get(username = redditor_name)
|
||||||
|
return render_to_response('redditors/view_profile.html',
|
||||||
|
context_instance = RequestContext(request, {'redditor': redditor})
|
||||||
|
)
|
||||||
|
except User.DoesNotExist:
|
||||||
|
return HttpResponse(status=404)
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,27 @@
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rounded_6px {
|
||||||
|
-moz-border-radius: 6px;
|
||||||
|
-webkit-border-radius: 6px;
|
||||||
|
-khtml-border-radius: 6px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rounded_4px {
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-khtml-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sandbox { clear: both; }
|
||||||
|
|
||||||
#title {
|
#title {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
background: #cee3f8;
|
background: #cee3f8;
|
||||||
|
background:-moz-linear-gradient(-90deg, #CEE3F8, #A8C4E0) repeat scroll 0 0 transparent;
|
||||||
background: -webkit-gradient(linear, left top, left bottom, from(#cee3f8), to(#a8c4e0));
|
background: -webkit-gradient(linear, left top, left bottom, from(#cee3f8), to(#a8c4e0));
|
||||||
padding: 7px 0 6px 0;
|
padding: 7px 0 6px 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
@ -45,6 +62,7 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
background: #cdcdcd;
|
background: #cdcdcd;
|
||||||
|
background:-moz-linear-gradient(-90deg, #fafafa, #cdcdcd) repeat scroll 0 0 transparent;
|
||||||
background: -webkit-gradient(linear, left top, left bottom, from(#fafafa), to(#cdcdcd));
|
background: -webkit-gradient(linear, left top, left bottom, from(#fafafa), to(#cdcdcd));
|
||||||
padding: 4px 0 6px;
|
padding: 4px 0 6px;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
|
|
@ -58,20 +76,27 @@
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
-webkit-border-radius: 4px;
|
-webkit-border-radius: 4px;
|
||||||
border: 1px solid #8f8f8f;
|
border: 1px solid #8f8f8f;
|
||||||
|
padding-bottom: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button {
|
.button {
|
||||||
background-color: #80A2C4;
|
background-color: #80A2C4;
|
||||||
border: 1px solid #517191;
|
border: 1px solid #517191;
|
||||||
|
background:-moz-linear-gradient(-90deg, #bfd0e0, #80a2c4) repeat scroll 0 0 transparent;
|
||||||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bfd0e0), to(#80a2c4));
|
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bfd0e0), to(#80a2c4));
|
||||||
-moz-border-radius: 6px;
|
|
||||||
-webkit-border-radius: 6px;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
padding: 3px 7px;
|
padding: 3px 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.orange_button {
|
||||||
|
border: 1px solid #ff4500;
|
||||||
|
background-color: #ff4500;
|
||||||
|
background:-moz-linear-gradient(-90deg, #ff9f7b, #ff4500) repeat scroll 0 0 transparent;
|
||||||
|
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ff9f7b), to(#ff4500));
|
||||||
|
}
|
||||||
|
|
||||||
.large {
|
.large {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 4px 10px;
|
padding: 4px 10px;
|
||||||
|
|
@ -86,9 +111,8 @@
|
||||||
#home_link, #nearby_link, #search_link, #find_link, #add_location {
|
#home_link, #nearby_link, #search_link, #find_link, #add_location {
|
||||||
background-color: #80A2C4;
|
background-color: #80A2C4;
|
||||||
border: 1px solid #517191;
|
border: 1px solid #517191;
|
||||||
|
background:-moz-linear-gradient(-90deg, #bfd0e0, #80a2c4) repeat scroll 0 0 transparent;
|
||||||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bfd0e0), to(#80a2c4));
|
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#bfd0e0), to(#80a2c4));
|
||||||
-moz-border-radius: 6px;
|
|
||||||
-webkit-border-radius: 6px;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
|
|
@ -102,11 +126,11 @@
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
/*color: #ff7041;*/
|
|
||||||
color: #6c7ca1;
|
color: #6c7ca1;
|
||||||
margin: 2px;
|
margin: 2px;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
background-color: #ebf3fc;
|
background-color: #ebf3fc;
|
||||||
|
background:-moz-linear-gradient(-90deg, #fafcfe, #ebf3fc) repeat scroll 0 0 transparent;
|
||||||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fafcfe), to(#ebf3fc));
|
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fafcfe), to(#ebf3fc));
|
||||||
border: 1px solid #c4dbf1;
|
border: 1px solid #c4dbf1;
|
||||||
}
|
}
|
||||||
|
|
@ -134,46 +158,48 @@
|
||||||
|
|
||||||
#button_center { text-align: center; }
|
#button_center { text-align: center; }
|
||||||
|
|
||||||
/* Oh god I'm so tired... */
|
|
||||||
.go_location {
|
|
||||||
width: 70px !important;
|
|
||||||
position: absolute;
|
|
||||||
top: 0px;
|
|
||||||
right: 10px;
|
|
||||||
color: #fff !important;
|
|
||||||
font-size: 14px !important;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 5px 12px !important;
|
|
||||||
text-align: center !important;
|
|
||||||
border: 1px solid #517191 !important;
|
|
||||||
-webkit-border-bottom-left-radius: 6px !important;
|
|
||||||
-webkit-border-bottom-right-radius: 6px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top_level {
|
.top_level {
|
||||||
margin-bottom: 10px;
|
border: 1px solid #c4dbf1;
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#results li a, #results li a:visited {
|
|
||||||
border: 1px solid #c9c9c9;
|
|
||||||
background-color: #f9f9f9;
|
|
||||||
-webkit-border-radius: 2px;
|
-webkit-border-radius: 2px;
|
||||||
padding: 10px;
|
-moz-border-radius: 2px;
|
||||||
display: block;
|
border-radius: 2px;
|
||||||
color: #555;
|
float: left;
|
||||||
text-decoration: none;
|
width: 99%;
|
||||||
padding-bottom: 3px;
|
padding-bottom: 5px;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 10px;
|
||||||
width: 92%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.location_name { font-weight: bold; color: #ff8070; }
|
.top_level h3 {
|
||||||
|
background-color: #ebf3fc;
|
||||||
.top_level ul { padding: 5px 0 0 0; }
|
background:-moz-linear-gradient(-90deg, #fafcfe, #ebf3fc) repeat scroll 0 0 transparent;
|
||||||
.top_level li { margin-bottom: 5px;}
|
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fafcfe), to(#ebf3fc));
|
||||||
|
border-bottom: 1px solid #c4dbf1;
|
||||||
|
margin: 0;
|
||||||
|
padding: 5px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #6C7CA1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top_level ul { padding: 5px; font-size: 12px; }
|
||||||
|
.top_level ul li { margin-bottom: 3px !important; }
|
||||||
|
.checkin_list_timestamp { color: #555; font-weight: normal; float: right; }
|
||||||
|
#results li a, #results li a:visited { text-decoration: none; }
|
||||||
|
|
||||||
|
.anchored_action {
|
||||||
|
float: right;
|
||||||
|
clear: right;
|
||||||
|
margin: 5px 5px 0 0;
|
||||||
|
width: auto !important;
|
||||||
|
color: #fff !important;
|
||||||
|
font-size: 12px !important;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: 3px 9px !important;
|
||||||
|
text-align: center !important;
|
||||||
|
-moz-border-radius: 6px;
|
||||||
|
-webkit-border-radius: 6px;
|
||||||
|
border-radius: 6px;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
@ -220,13 +246,16 @@
|
||||||
if(typeof _GPS !== "undefined") _GPS.getLocation();
|
if(typeof _GPS !== "undefined") _GPS.getLocation();
|
||||||
|
|
||||||
bareddit.about = document.getElementById("about");
|
bareddit.about = document.getElementById("about");
|
||||||
|
bareddit.about_button = document.getElementById("about_button");
|
||||||
|
|
||||||
/* Use the annoying event handler syntax in the hopes of hitting all odd mobile browsers.
|
/* Use the annoying event handler syntax in the hopes of hitting all odd mobile browsers.
|
||||||
touchstart events are faster in the browsers that support them, so fork for it */
|
touchstart events are faster in the browsers that support them, so fork for it */
|
||||||
|
if(bareddit.about_button) {
|
||||||
if(isEventSupported('touchstart')) {
|
if(isEventSupported('touchstart')) {
|
||||||
document.getElementById("about_button").ontouchstart = bareddit.toggleAbout;
|
bareddit.about_button.ontouchstart = bareddit.toggleAbout;
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("about_button").onclick = bareddit.toggleAbout;
|
bareddit.about_button.onclick = bareddit.toggleAbout;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
@ -234,11 +263,11 @@
|
||||||
<body onload="whenReady();">
|
<body onload="whenReady();">
|
||||||
<div id="title">
|
<div id="title">
|
||||||
{% if not user.is_authenticated %}
|
{% if not user.is_authenticated %}
|
||||||
<a href="/auth/" id="login_button" class="button">Login</a>
|
<a href="/auth/" id="login_button" class="button rounded_6px">Login</a>
|
||||||
<a href="/register/" id="register_button" class="button">Register</a>
|
<a href="/register/" id="register_button" class="button rounded_6px">Register</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="#" id="about_button" class="button">About</a>
|
<a href="#" id="about_button" class="button rounded_6px">About</a>
|
||||||
<a href="/unauth/" id="login_button" class="button">Logout</a>
|
<a href="/unauth/" id="login_button" class="button rounded_6px">Logout</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
drinkkit
|
drinkkit
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -250,11 +279,11 @@
|
||||||
|
|
||||||
- Ryan, 3:45AM
|
- Ryan, 3:45AM
|
||||||
-->
|
-->
|
||||||
<a href="/" id="home_link" class="button">Home</a>
|
<a href="/" id="home_link" class="button rounded_6px">Home</a>
|
||||||
<a href="/locations/nearby/" id="nearby_link" class="button">Nearby</a>
|
<a href="/locations/nearby/" id="nearby_link" class="button rounded_6px">Nearby</a>
|
||||||
<a href="/locations/search/" id="search_link" class="button">Search</a>
|
<a href="/locations/search/" id="search_link" class="button rounded_6px">Search</a>
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<a href="/locations/add/" id="add_location" class="button">Add Location</a>
|
<a href="/locations/add/" id="add_location" class="button rounded_6px">Add Location</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -287,5 +316,7 @@
|
||||||
<div id="junk_in_trunk">
|
<div id="junk_in_trunk">
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
<div>
|
<div>
|
||||||
|
|
||||||
|
<div id="sandbox"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ _GPS.getLocation = function() {
|
||||||
<input type="hidden" name="long" id="long" value="">
|
<input type="hidden" name="long" id="long" value="">
|
||||||
|
|
||||||
<div id="button_center">
|
<div id="button_center">
|
||||||
<input type="submit" value="Add This Location" id="add_location_submit" class="button large">
|
<input type="submit" value="Add This Location" id="add_location_submit" class="button large rounded_6px">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div id="button_center" style="margin-bottom: 14px;">
|
<div id="button_center" style="margin-bottom: 14px;">
|
||||||
<input type="submit" value="Check In Here!" class="button large">
|
<input type="submit" value="Check In Here!" class="button large rounded_6px">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ _GPS.getLocation = function() {
|
||||||
<input type="hidden" name="long" id="long" value="">
|
<input type="hidden" name="long" id="long" value="">
|
||||||
|
|
||||||
<div id="button_center">
|
<div id="button_center">
|
||||||
<input type="submit" value="Add This Location" id="add_location_submit" class="button large">
|
<input type="submit" value="Add This Location" id="add_location_submit" class="button large rounded_6px">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="bert" style="margin-bottom: 10px;">
|
<div id="bert" style="margin-bottom: 10px;">
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
<h2>Where all the DC Redditors at?</h2>
|
<h2>Where all the DC Redditors at?</h2>
|
||||||
<p>
|
<p>
|
||||||
Check out where other DC Redditors are drinking! If you'd like to join in, register or log in using the buttons
|
Check out where other DC Redditors are drinking! If you'd like to join in, register or log in using the buttons
|
||||||
at the top right of the screen.
|
at the top of the screen.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -21,13 +21,14 @@
|
||||||
<ul id="results">
|
<ul id="results">
|
||||||
{% for checkin in checkins.object_list %}
|
{% for checkin in checkins.object_list %}
|
||||||
<li class="top_level">
|
<li class="top_level">
|
||||||
<a href="/locations/{{ checkin.location.id }}/" class="go_location button">View</a>
|
<h3>{{ checkin.user.username }} <span class="checkin_list_timestamp">{{ checkin.timestamp|timesince }} ago</span></h3>
|
||||||
<a href="/locations/{{ checkin.location.id }}/">
|
<a href="/locations/{{ checkin.location.id }}/" class="anchored_action button orange_button">View Location</a>
|
||||||
<span class="location_name">{{ checkin.location.name }}</span>
|
<a href="/redditor/{{ checkin.user.username }}/" class="anchored_action button">View User</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>{{ checkin.user.username }}</strong> checked in here {{ checkin.timestamp|timesince }} ago</li>
|
<li><strong>Checked in at:</strong> {{ checkin.location.name }}</li>
|
||||||
|
<li><strong>Identify by:</strong> {{ checkin.identify_by }}</li>
|
||||||
|
<li><strong>Should be there for:</strong> {{ checkin.estimated_time_here }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</a>
|
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div id="button_center">
|
<div id="button_center">
|
||||||
<input type="submit" value="Find Locations" id="search_btn" class="button large">
|
<input type="submit" value="Find Locations" id="search_btn" class="button large rounded_6px">
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
@ -32,16 +32,15 @@
|
||||||
<ul id="results">
|
<ul id="results">
|
||||||
{% for location in results.object_list %}
|
{% for location in results.object_list %}
|
||||||
<li class="top_level">
|
<li class="top_level">
|
||||||
<a href="/locations/{{ checkin.location.id }}/" class="go_location button">View</a>
|
<h3>{{ location.name }}</h3>
|
||||||
<a href="/locations/{{ location.id }}/">
|
<a href="/locations/{{ location.id }}/" class="anchored_action button orange_button">View Location</a>
|
||||||
<span class="location_name">{{ location.name }}</span>
|
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Recent Checkins:</strong> {{ location.get_recent_checkins_count }}</li>
|
<li><strong>Recent Checkins:</strong> {{ location.get_recent_checkins_count }}</li>
|
||||||
<li><strong>Address:</strong> {{ location.street_address|default:"No address set" }}</li>
|
<li><strong>Address:</strong> {{ location.street_address|default:"No address set" }}</li>
|
||||||
<li><strong>Category:</strong> {{ location.category|default:"No category set" }}</li>
|
<li><strong>Category:</strong> {{ location.category|default:"No category set" }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
</a>
|
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,29 +43,29 @@
|
||||||
|
|
||||||
#checkin_here_link, #checked_in_already {
|
#checkin_here_link, #checked_in_already {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 5px;
|
||||||
right: 10px;
|
right: 8px;
|
||||||
-moz-border-radius: 4px;
|
-moz-border-radius: 4px;
|
||||||
-webkit-border-radius: 4px;
|
-webkit-border-radius: 4px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
padding: 3px 7px !important;
|
||||||
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#checked_in_already { padding: 3px !important; font-size: 11px !important; top: 5px; /* I'm tired, hush */ }
|
||||||
|
|
||||||
#checkin_here_link {
|
#checkin_here_link {
|
||||||
background-color: #ff4500;
|
background-color: #ff4500;
|
||||||
border: 1px solid #ff4500;
|
border: 1px solid #ff4500;
|
||||||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ff9f7b), to(#ff4500));
|
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ff9f7b), to(#ff4500));
|
||||||
font-size: 20px;
|
|
||||||
padding: 7px 12px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#checked_in_already {
|
#checked_in_already {
|
||||||
background-color: #cdcdcd;
|
background-color: #cdcdcd;
|
||||||
border: 1px solid #8f8f8f;
|
border: 1px solid #8f8f8f;
|
||||||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f2f2f2), to(#cdcdcd));
|
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f2f2f2), to(#cdcdcd));
|
||||||
font-size: 14px;
|
|
||||||
padding: 7px 10px;
|
|
||||||
color: #888;
|
color: #888;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,10 +160,13 @@
|
||||||
{% if recent_checkins %}
|
{% if recent_checkins %}
|
||||||
<ul id="checkins">
|
<ul id="checkins">
|
||||||
{% for checkin in recent_checkins %}
|
{% for checkin in recent_checkins %}
|
||||||
<li>
|
<li class="top_level">
|
||||||
<span class="comment_header"><strong>{{ checkin.user.username }}</strong> <em>{{ checkin.timestamp|timesince }} ago</em></span>
|
<h3>{{ checkin.user.username }} <span class="checkin_list_timestamp">{{ checkin.timestamp|timesince }} ago</span></h3>
|
||||||
<span class="pointers">Can be identified by:</span> {{ checkin.identify_by|default:"Doesn't want to be found. :(" }}<br>
|
<a href="/redditor/{{ checkin.user.username }}/" class="anchored_action button">View User</a>
|
||||||
<span class="pointers">Estimated time spent here:</span> {{ checkin.estimated_time_here|default:"They're flying by the seat of their vintage pants (no idea)."}}
|
<ul>
|
||||||
|
<li><strong>Identify by:</strong> {{ checkin.identify_by }}</li>
|
||||||
|
<li><strong>Should be there for:</strong> {{ checkin.estimated_time_here }}</li>
|
||||||
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -171,13 +174,15 @@
|
||||||
<p class="none_yet">No checkins yet. You could be the first!</p>
|
<p class="none_yet">No checkins yet. You could be the first!</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<div style="clear: both;"><!-- It's 5AM and I have better things to do with my time... like sleep. --></div>
|
||||||
|
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<h2>Leave a Tip or Todo</h2>
|
<h2>Leave a Tip or Todo</h2>
|
||||||
<form action="/locations/{{ location.id }}/add_tip/" method="post" id="bert">
|
<form action="/locations/{{ location.id }}/add_tip/" method="post" id="bert">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
|
||||||
<textarea name="tip_body" id="tip_body"></textarea>
|
<textarea name="tip_body" id="tip_body"></textarea>
|
||||||
<input type="submit" value="Post Tip" id="submit_tip" class="button large">
|
<input type="submit" value="Post Tip" id="submit_tip" class="button large rounded_6px">
|
||||||
</form>
|
</form>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
|
||||||
22
templates/redditors/view_profile.html
Normal file
22
templates/redditors/view_profile.html
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block extra_head %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h2>Where has {{ redditor.username }} been?</h2>
|
||||||
|
|
||||||
|
<ul id="results">
|
||||||
|
{% for checkin in redditor.checkin_set.all %}
|
||||||
|
<li class="top_level">
|
||||||
|
<h3>{{ checkin.location.name }} <span class="checkin_list_timestamp">{{ checkin.timestamp|timesince }} ago</span></h3>
|
||||||
|
<a href="/locations/{{ checkin.location.id }}/" class="anchored_action button orange_button">View Location</a>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Was identifiable by:</strong> {{ checkin.identify_by }}</li>
|
||||||
|
<li><strong>Was there for:</strong> {{ checkin.estimated_time_here }}</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
5
urls.py
5
urls.py
|
|
@ -5,7 +5,7 @@ from django.contrib import admin
|
||||||
admin.autodiscover()
|
admin.autodiscover()
|
||||||
|
|
||||||
urlpatterns = patterns('',
|
urlpatterns = patterns('',
|
||||||
(r'^admin/', include(admin.site.urls)),
|
(r'^knux/', include(admin.site.urls)),
|
||||||
|
|
||||||
# Viewing and adding tips/locations
|
# Viewing and adding tips/locations
|
||||||
(r'^locations/add/$', 'drinkkit.redditors.views.add_location'),
|
(r'^locations/add/$', 'drinkkit.redditors.views.add_location'),
|
||||||
|
|
@ -16,6 +16,9 @@ urlpatterns = patterns('',
|
||||||
(r'^locations/(?P<location_id>[a-zA-Z0-9_.-]+)/checkin/$', 'drinkkit.redditors.views.checkin_location'),
|
(r'^locations/(?P<location_id>[a-zA-Z0-9_.-]+)/checkin/$', 'drinkkit.redditors.views.checkin_location'),
|
||||||
(r'^locations/(?P<location_id>[a-zA-Z0-9_.-]+)/$', 'drinkkit.redditors.views.view_location'),
|
(r'^locations/(?P<location_id>[a-zA-Z0-9_.-]+)/$', 'drinkkit.redditors.views.view_location'),
|
||||||
|
|
||||||
|
# Query and see who's getting into what
|
||||||
|
(r'^redditor/(?P<redditor_name>[a-zA-Z0-9_.-]+)/$', 'drinkkit.redditors.views.view_redditor'),
|
||||||
|
|
||||||
# Registration
|
# Registration
|
||||||
(r'^register/$', 'drinkkit.redditors.views.register'),
|
(r'^register/$', 'drinkkit.redditors.views.register'),
|
||||||
|
|
||||||
|
|
|
||||||
Reference in a new issue