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)
|
||||
street_address = models.CharField(max_length=200, blank=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()
|
||||
|
||||
def __str__(self):
|
||||
|
|
@ -33,7 +33,6 @@ class Location(models.Model):
|
|||
"""
|
||||
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()
|
||||
|
||||
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 django.contrib.gis.geos import *
|
||||
from django.contrib.gis.measure import D
|
||||
|
||||
from django import forms
|
||||
from django.contrib.auth.forms import UserCreationForm
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
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.contrib.auth.decorators import login_required
|
||||
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
|
||||
|
||||
|
|
@ -153,28 +162,57 @@ def add_location(request):
|
|||
fixed at some point. ;P
|
||||
"""
|
||||
if request.POST:
|
||||
if request.POST['location_name'] and request.POST['lat'] and request.POST['long']:
|
||||
new_location = Location()
|
||||
new_location.name = request.POST['location_name']
|
||||
new_location.geometry = 'POINT(%s %s)' %(request.POST['lat'], 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.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'])
|
||||
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 request.POST['street_address']:
|
||||
new_location.street_address = request.POST['street_address']
|
||||
|
||||
# If they've supplied a street address, sweet, use it.
|
||||
if request.POST['street_address']:
|
||||
new_location.street_address = request.POST['street_address']
|
||||
# If they set a location type/category, let's record it... (5AM code)
|
||||
if request.POST['location_type']:
|
||||
try:
|
||||
category = LocationCategory.objects.get(id = request.POST['location_type'])
|
||||
new_location.category = category
|
||||
except LocationCategory.DoesNotExist:
|
||||
pass
|
||||
|
||||
# If they set a location, let's record it... (5AM code)
|
||||
if request.POST['location_type']:
|
||||
try:
|
||||
category = LocationCategory.objects.get(id = request.POST['location_type'])
|
||||
new_location.category = category
|
||||
except LocationCategory.DoesNotExist:
|
||||
pass
|
||||
|
||||
new_location.save()
|
||||
return HttpResponseRedirect('/locations/%s/' % str(new_location.id))
|
||||
new_location.save()
|
||||
return HttpResponseRedirect('/locations/%s/' % str(new_location.id))
|
||||
else:
|
||||
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']:
|
||||
errmsg = "You didn't even bother to enter a name for this location. Wtf?"
|
||||
return render_to_response('locations/add.html',
|
||||
|
|
@ -235,8 +273,17 @@ def add_tip(request, location_id):
|
|||
else:
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@
|
|||
body {
|
||||
width: 100%;
|
||||
color: #555;
|
||||
font-family:Helvetica, "Helvetica Neue", Arial, sans-serif;
|
||||
font-family: Helvetica, "Helvetica Neue", Arial, sans-serif;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background:#c5ccd3;
|
||||
background: #c5ccd3;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
|
|
@ -26,11 +26,28 @@
|
|||
padding: 10px 12px;
|
||||
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 {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
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));
|
||||
padding: 7px 0 6px 0;
|
||||
margin: 0;
|
||||
|
|
@ -45,6 +62,7 @@
|
|||
width: 100%;
|
||||
position: relative;
|
||||
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));
|
||||
padding: 4px 0 6px;
|
||||
font-size: 1.2em;
|
||||
|
|
@ -58,20 +76,27 @@
|
|||
background-color: #fff;
|
||||
-webkit-border-radius: 4px;
|
||||
border: 1px solid #8f8f8f;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.button {
|
||||
background-color: #80A2C4;
|
||||
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));
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
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 {
|
||||
font-size: 14px;
|
||||
padding: 4px 10px;
|
||||
|
|
@ -86,9 +111,8 @@
|
|||
#home_link, #nearby_link, #search_link, #find_link, #add_location {
|
||||
background-color: #80A2C4;
|
||||
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));
|
||||
-moz-border-radius: 6px;
|
||||
-webkit-border-radius: 6px;
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
|
|
@ -102,11 +126,11 @@
|
|||
|
||||
h2 {
|
||||
font-size: 18px;
|
||||
/*color: #ff7041;*/
|
||||
color: #6c7ca1;
|
||||
margin: 2px;
|
||||
padding: 8px;
|
||||
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));
|
||||
border: 1px solid #c4dbf1;
|
||||
}
|
||||
|
|
@ -133,47 +157,49 @@
|
|||
}
|
||||
|
||||
#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 {
|
||||
margin-bottom: 10px;
|
||||
position: relative;
|
||||
}
|
||||
.top_level {
|
||||
border: 1px solid #c4dbf1;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
float: left;
|
||||
width: 99%;
|
||||
padding-bottom: 5px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#results li a, #results li a:visited {
|
||||
border: 1px solid #c9c9c9;
|
||||
background-color: #f9f9f9;
|
||||
-webkit-border-radius: 2px;
|
||||
padding: 10px;
|
||||
display: block;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
padding-bottom: 3px;
|
||||
margin-bottom: 5px;
|
||||
width: 92%;
|
||||
}
|
||||
|
||||
.location_name { font-weight: bold; color: #ff8070; }
|
||||
|
||||
.top_level ul { padding: 5px 0 0 0; }
|
||||
.top_level li { margin-bottom: 5px;}
|
||||
.top_level h3 {
|
||||
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));
|
||||
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>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
|
@ -220,13 +246,16 @@
|
|||
if(typeof _GPS !== "undefined") _GPS.getLocation();
|
||||
|
||||
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.
|
||||
touchstart events are faster in the browsers that support them, so fork for it */
|
||||
if(isEventSupported('touchstart')) {
|
||||
document.getElementById("about_button").ontouchstart = bareddit.toggleAbout;
|
||||
} else {
|
||||
document.getElementById("about_button").onclick = bareddit.toggleAbout;
|
||||
if(bareddit.about_button) {
|
||||
if(isEventSupported('touchstart')) {
|
||||
bareddit.about_button.ontouchstart = bareddit.toggleAbout;
|
||||
} else {
|
||||
bareddit.about_button.onclick = bareddit.toggleAbout;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -234,11 +263,11 @@
|
|||
<body onload="whenReady();">
|
||||
<div id="title">
|
||||
{% if not user.is_authenticated %}
|
||||
<a href="/auth/" id="login_button" class="button">Login</a>
|
||||
<a href="/register/" id="register_button" class="button">Register</a>
|
||||
<a href="/auth/" id="login_button" class="button rounded_6px">Login</a>
|
||||
<a href="/register/" id="register_button" class="button rounded_6px">Register</a>
|
||||
{% else %}
|
||||
<a href="#" id="about_button" class="button">About</a>
|
||||
<a href="/unauth/" id="login_button" class="button">Logout</a>
|
||||
<a href="#" id="about_button" class="button rounded_6px">About</a>
|
||||
<a href="/unauth/" id="login_button" class="button rounded_6px">Logout</a>
|
||||
{% endif %}
|
||||
drinkkit
|
||||
</div>
|
||||
|
|
@ -250,11 +279,11 @@
|
|||
|
||||
- Ryan, 3:45AM
|
||||
-->
|
||||
<a href="/" id="home_link" class="button">Home</a>
|
||||
<a href="/locations/nearby/" id="nearby_link" class="button">Nearby</a>
|
||||
<a href="/locations/search/" id="search_link" class="button">Search</a>
|
||||
<a href="/" id="home_link" class="button rounded_6px">Home</a>
|
||||
<a href="/locations/nearby/" id="nearby_link" class="button rounded_6px">Nearby</a>
|
||||
<a href="/locations/search/" id="search_link" class="button rounded_6px">Search</a>
|
||||
{% 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 %}
|
||||
</div>
|
||||
|
||||
|
|
@ -287,5 +316,7 @@
|
|||
<div id="junk_in_trunk">
|
||||
{% block content %}{% endblock %}
|
||||
<div>
|
||||
|
||||
<div id="sandbox"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ _GPS.getLocation = function() {
|
|||
<input type="hidden" name="long" id="long" value="">
|
||||
|
||||
<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>
|
||||
</form>
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
</p>
|
||||
|
||||
<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>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ _GPS.getLocation = function() {
|
|||
<input type="hidden" name="long" id="long" value="">
|
||||
|
||||
<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 id="bert" style="margin-bottom: 10px;">
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<h2>Where all the DC Redditors at?</h2>
|
||||
<p>
|
||||
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>
|
||||
|
|
@ -21,13 +21,14 @@
|
|||
<ul id="results">
|
||||
{% for checkin in checkins.object_list %}
|
||||
<li class="top_level">
|
||||
<a href="/locations/{{ checkin.location.id }}/" class="go_location button">View</a>
|
||||
<a href="/locations/{{ checkin.location.id }}/">
|
||||
<span class="location_name">{{ checkin.location.name }}</span>
|
||||
<ul>
|
||||
<li><strong>{{ checkin.user.username }}</strong> checked in here {{ checkin.timestamp|timesince }} ago</li>
|
||||
</ul>
|
||||
</a>
|
||||
<h3>{{ checkin.user.username }} <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>
|
||||
<a href="/redditor/{{ checkin.user.username }}/" class="anchored_action button">View User</a>
|
||||
<ul>
|
||||
<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>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
</p>
|
||||
|
||||
<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>
|
||||
</form>
|
||||
|
||||
|
|
@ -32,16 +32,15 @@
|
|||
<ul id="results">
|
||||
{% for location in results.object_list %}
|
||||
<li class="top_level">
|
||||
<a href="/locations/{{ checkin.location.id }}/" class="go_location button">View</a>
|
||||
<a href="/locations/{{ location.id }}/">
|
||||
<span class="location_name">{{ location.name }}</span>
|
||||
<ul>
|
||||
<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>Category:</strong> {{ location.category|default:"No category set" }}</li>
|
||||
</ul>
|
||||
</a>
|
||||
<h3>{{ location.name }}</h3>
|
||||
<a href="/locations/{{ location.id }}/" class="anchored_action button orange_button">View Location</a>
|
||||
<ul>
|
||||
<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>Category:</strong> {{ location.category|default:"No category set" }}</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -43,29 +43,29 @@
|
|||
|
||||
#checkin_here_link, #checked_in_already {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
top: 5px;
|
||||
right: 8px;
|
||||
-moz-border-radius: 4px;
|
||||
-webkit-border-radius: 4px;
|
||||
text-decoration: none;
|
||||
color: #fff;
|
||||
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 {
|
||||
background-color: #ff4500;
|
||||
border: 1px solid #ff4500;
|
||||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#ff9f7b), to(#ff4500));
|
||||
font-size: 20px;
|
||||
padding: 7px 12px;
|
||||
}
|
||||
|
||||
#checked_in_already {
|
||||
background-color: #cdcdcd;
|
||||
border: 1px solid #8f8f8f;
|
||||
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#f2f2f2), to(#cdcdcd));
|
||||
font-size: 14px;
|
||||
padding: 7px 10px;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
|
|
@ -160,10 +160,13 @@
|
|||
{% if recent_checkins %}
|
||||
<ul id="checkins">
|
||||
{% for checkin in recent_checkins %}
|
||||
<li>
|
||||
<span class="comment_header"><strong>{{ checkin.user.username }}</strong> <em>{{ checkin.timestamp|timesince }} ago</em></span>
|
||||
<span class="pointers">Can be identified by:</span> {{ checkin.identify_by|default:"Doesn't want to be found. :(" }}<br>
|
||||
<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)."}}
|
||||
<li class="top_level">
|
||||
<h3>{{ checkin.user.username }} <span class="checkin_list_timestamp">{{ checkin.timestamp|timesince }} ago</span></h3>
|
||||
<a href="/redditor/{{ checkin.user.username }}/" class="anchored_action button">View User</a>
|
||||
<ul>
|
||||
<li><strong>Identify by:</strong> {{ checkin.identify_by }}</li>
|
||||
<li><strong>Should be there for:</strong> {{ checkin.estimated_time_here }}</li>
|
||||
</ul>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
|
@ -171,13 +174,15 @@
|
|||
<p class="none_yet">No checkins yet. You could be the first!</p>
|
||||
{% 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 %}
|
||||
<h2>Leave a Tip or Todo</h2>
|
||||
<form action="/locations/{{ location.id }}/add_tip/" method="post" id="bert">
|
||||
{% csrf_token %}
|
||||
|
||||
<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>
|
||||
{% 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()
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^admin/', include(admin.site.urls)),
|
||||
(r'^knux/', include(admin.site.urls)),
|
||||
|
||||
# Viewing and adding tips/locations
|
||||
(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_.-]+)/$', '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
|
||||
(r'^register/$', 'drinkkit.redditors.views.register'),
|
||||
|
||||
|
|
|
|||
Reference in a new issue