More cleanup
moved login, logout and password change from website app to musicians
This commit is contained in:
@@ -9,6 +9,11 @@ from datetime import datetime
|
||||
from location_field.models import PlainLocationField
|
||||
|
||||
|
||||
class NoNextEventException( Exception ):
|
||||
def __str__(self):
|
||||
return ("No event scheduled for the future")
|
||||
|
||||
|
||||
class Event ( models.Model ):
|
||||
|
||||
EVENT_TYPES = (
|
||||
@@ -64,11 +69,50 @@ class Event ( models.Model ):
|
||||
@property
|
||||
def displaydatetime(self):
|
||||
if not self.displaytime == None:
|
||||
return datetime.combine( self.date, self.displaytime() )
|
||||
return datetime.combine( self.date, self.displaytime )
|
||||
else:
|
||||
return datetime.combine( self.date, datetime.min.time())
|
||||
return datetime.combine( self.date, datetime.min.time() )
|
||||
|
||||
@staticmethod
|
||||
def getNextEvent( eventType = "", includePreviousFromToday = True ):
|
||||
"""Return the next event, of the given type. If type is the empty string the next event is returned
|
||||
regardless of its type.
|
||||
if includePreviousFromToday the nextEvent returned could also have been today with a startime < now """
|
||||
|
||||
if includePreviousFromToday:
|
||||
if eventType == "":
|
||||
nextEvents = Event.objects.filter( date__gte = datetime.now() ).order_by('date')[:1]
|
||||
else:
|
||||
nextEvents = Event.objects.filter( date__gte = datetime.now(), type = eventType ).order_by('date')[:1]
|
||||
|
||||
if len( nextEvents ) == 0:
|
||||
raise NoNextEventException()
|
||||
|
||||
return nextEvents[0]
|
||||
else:
|
||||
maximalNumberOfEventsOnSameDay = 4
|
||||
nextEvents = []
|
||||
if eventType =="":
|
||||
nextEvents = Event.objects.filter( date__gte = datetime.now() ).order_by('date')[:maximalNumberOfEventsOnSameDay]
|
||||
else:
|
||||
nextEvents = Event.objects.filter( date__gte = datetime.now(), type = eventType ).order_by('date')[:maximalNumberOfEventsOnSameDay]
|
||||
|
||||
if len(nextEvents) == 0:
|
||||
raise NoNextEventException()
|
||||
|
||||
|
||||
i = 0
|
||||
nextEvent = nextEvents[0]
|
||||
# nextEvent is not necessarily events[0] since events[0] may have been previously today
|
||||
while nextEvent.displaydatetime < datetime.now():
|
||||
if len(nextEvents ) <= i:
|
||||
raise NoNextEventException()
|
||||
else:
|
||||
i += 1
|
||||
nextEvent = nextEvents[i]
|
||||
|
||||
return nextEvent
|
||||
|
||||
|
||||
class EventParticipation( models.Model ):
|
||||
OPTIONS = ( ('?' , _('?' )),
|
||||
|
||||
55
eventplanner/snippets.py
Normal file
55
eventplanner/snippets.py
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
from datetime import datetime
|
||||
from models import Event, EventParticipation, NoNextEventException
|
||||
from musicians.models import Musician
|
||||
|
||||
|
||||
|
||||
def addEventCountdownForNextEventToContext( context, username, eventType = "" ):
|
||||
"""Returns an object that has to be added to the render context on the page where the countdown
|
||||
should be displayed . The username is required to also supply participation information."""
|
||||
|
||||
try:
|
||||
nextEvent = Event.getNextEvent( eventType, False )
|
||||
except NoNextEventException:
|
||||
return
|
||||
|
||||
countdown = dict()
|
||||
|
||||
if EventParticipation.isMember( username ):
|
||||
part = EventParticipation.objects.filter( user = username ).filter( event = nextEvent )
|
||||
countdown['participation'] = part[0].status
|
||||
|
||||
eventTime = nextEvent.displaydatetime
|
||||
countdown['event'] = nextEvent
|
||||
countdown['epoch'] = int( (eventTime - datetime.now() ).total_seconds() * 1000 )
|
||||
|
||||
context["countdown"] = countdown
|
||||
|
||||
|
||||
def addEventRouteForNextEventToContext( context, username, eventType = ""):
|
||||
"""Returns an object that has to be added to the render context on the page where the route
|
||||
should be displayed . The starting address of the route will be the home of the specified user"""
|
||||
|
||||
try:
|
||||
nextEvent = Event.getNextEvent( eventType, True )
|
||||
except NoNextEventException:
|
||||
return
|
||||
|
||||
routeInfo = dict()
|
||||
|
||||
routeInfo['event'] = nextEvent
|
||||
|
||||
musician = Musician.objects.get( user = username );
|
||||
routeInfo['origin'] = musician.street + ", " + str( musician.zip_code ) + " " + musician.city
|
||||
|
||||
if nextEvent.map_location:
|
||||
# map_location has format "lat,longitute,zoomlevel"
|
||||
routeInfo['destination'] = ",".join( nextEvent.map_location.split(",")[:2] )
|
||||
else:
|
||||
routeInfo['destination'] = nextEvent.location
|
||||
|
||||
|
||||
context["route"] = routeInfo
|
||||
|
||||
|
||||
79
eventplanner/templates/eventplanner/countdown.inc.html
Normal file
79
eventplanner/templates/eventplanner/countdown.inc.html
Normal file
@@ -0,0 +1,79 @@
|
||||
{% load sekizai_tags staticfiles %}
|
||||
|
||||
|
||||
|
||||
{% addtoblock "css" strip %}<link rel="stylesheet" type="text/css" href="{{STATIC_URL}}/css/lib/animate.css" media="screen, projection">{% endaddtoblock %}
|
||||
{% addtoblock "css" strip %}<link rel="stylesheet" href="{{STATIC_URL}}/css/coming-soon.css" type="text/css" media="screen" />{% endaddtoblock %}
|
||||
|
||||
{% if countdown %}
|
||||
|
||||
|
||||
|
||||
{% addtoblock "js" %}
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
function callback(event) {
|
||||
$this = $(this);
|
||||
$this.find('span#'+event.type).html(event.value);
|
||||
switch(event.type) {
|
||||
case "seconds":
|
||||
case "minutes":
|
||||
case "hours":
|
||||
case "days":
|
||||
case "weeks":
|
||||
case "daysLeft":
|
||||
case "finished":
|
||||
}
|
||||
}
|
||||
$('div#clock').countdown(new Date().valueOf() + {{ countdown.epoch }} , callback);
|
||||
});
|
||||
</script>
|
||||
{% endaddtoblock %}
|
||||
|
||||
|
||||
|
||||
<div id="coming_soon">
|
||||
<div class="head">
|
||||
<div class="container">
|
||||
<div class="span6 text">
|
||||
<h4>Der nächste Termin:</h4>
|
||||
<p>
|
||||
{{countdown.event.title}} am {{countdown.event.date | date:"D, d.m.y" }}
|
||||
{% if coundown.event.displaytime %} um {{countdown.event.displaytime | time:"H:i" }} Uhr {% endif %}
|
||||
{% if coundown.event.location %} in <em>{{countdown.event.location}} </em> {% endif %}
|
||||
|
||||
<br/>
|
||||
{% if 'participation' in countdown %}
|
||||
{% if countdown.participation == "?" %}
|
||||
Du hast dich noch nicht für diesen Termin eingetragen!
|
||||
{% elif countdown.participation == "Yes" %}
|
||||
Du hast für diesen Termin zugesagt.
|
||||
{% elif countdown.participation == "No" %}
|
||||
Du hast für diesen Termin abgesagt.
|
||||
{%endif %}
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="span6 count" id="clock">
|
||||
<div class="box">
|
||||
<div class="circle"> <span id="days"></span> </div>
|
||||
<p>Tage</p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="circle"> <span id="hours"></span> </div>
|
||||
<p>Stunden</p>
|
||||
</div>
|
||||
<div class="box">
|
||||
<div class="circle"> <span id="minutes"></span> </div>
|
||||
<p>Minuten</p>
|
||||
</div>
|
||||
<div class="box last">
|
||||
<div class="circle"> <span id="seconds"></span> </div>
|
||||
<p>Sekunden</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
208
eventplanner/templates/eventplanner/routeToEventMap.inc.html
Normal file
208
eventplanner/templates/eventplanner/routeToEventMap.inc.html
Normal file
@@ -0,0 +1,208 @@
|
||||
{% comment %}
|
||||
Displays google map with directions to next conert
|
||||
|
||||
Context:
|
||||
Coordinates or textual adresses:
|
||||
{{route.origin}}
|
||||
{{route.destination}}
|
||||
Event object:
|
||||
{{route.event}}
|
||||
{% endcomment %}
|
||||
|
||||
|
||||
|
||||
|
||||
{% load sekizai_tags staticfiles %}
|
||||
|
||||
|
||||
{% if route %}
|
||||
|
||||
{% addtoblock "css" strip %}<link rel="stylesheet" href="{{STATIC_URL}}/css/concert_route.css" type="text/css" media="screen" />{% endaddtoblock %}
|
||||
{% addtoblock "js" strip %}<script type="text/javascript" src="//maps.google.com/maps/api/js?sensor=false&language=de"></script>{% endaddtoblock %}
|
||||
|
||||
|
||||
{% addtoblock "js" %}
|
||||
<script type="text/javascript">
|
||||
|
||||
function OpenWindowControl(controlDiv, map) {
|
||||
// Set CSS styles for the DIV containing the control
|
||||
// Setting padding to 5 px will offset the control
|
||||
// from the edge of the map
|
||||
controlDiv.style.paddingTop = '6px';
|
||||
|
||||
// Set CSS for the control border
|
||||
var controlUI = document.createElement('div');
|
||||
controlUI.style.backgroundColor = 'white';
|
||||
controlUI.style.borderStyle = 'solid';
|
||||
controlUI.style.borderWidth = '1px';
|
||||
controlUI.style.cursor = 'pointer';
|
||||
controlUI.style.textAlign = 'center';
|
||||
controlUI.title = 'Fenster mit Konzert Info anzeigen';
|
||||
controlDiv.appendChild(controlUI);
|
||||
|
||||
// Set CSS for the control interior
|
||||
var controlText = document.createElement('div');
|
||||
controlText.style.fontFamily = 'Arial,sans-serif';
|
||||
controlText.style.fontSize = '12px';
|
||||
controlText.style.paddingLeft = '4px';
|
||||
controlText.style.paddingRight = '4px';
|
||||
controlText.innerHTML = 'Konzert Info anzeigen';
|
||||
controlUI.appendChild(controlText);
|
||||
|
||||
google.maps.event.addDomListener(controlUI, 'click', function() {
|
||||
$("#map_box").show();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function ShowTargetControl(controlDiv, map) {
|
||||
// Set CSS styles for the DIV containing the control
|
||||
// Setting padding to 5 px will offset the control
|
||||
// from the edge of the map
|
||||
controlDiv.style.paddingTop = '6px';
|
||||
controlDiv.style.paddingRight = '6px';
|
||||
|
||||
// Set CSS for the control border
|
||||
var controlUI = document.createElement('div');
|
||||
controlUI.style.backgroundColor = 'white';
|
||||
controlUI.style.borderStyle = 'solid';
|
||||
controlUI.style.borderWidth = '1px';
|
||||
controlUI.style.cursor = 'pointer';
|
||||
controlUI.style.textAlign = 'center';
|
||||
controlUI.title = 'Zum Zielpunkt springen';
|
||||
controlDiv.appendChild(controlUI);
|
||||
|
||||
// Set CSS for the control interior
|
||||
var controlText = document.createElement('div');
|
||||
controlText.style.fontFamily = 'Arial,sans-serif';
|
||||
controlText.style.fontSize = '12px';
|
||||
controlText.style.paddingLeft = '4px';
|
||||
controlText.style.paddingRight = '4px';
|
||||
controlText.innerHTML = 'Konzertort anzeigen';
|
||||
controlUI.appendChild(controlText);
|
||||
|
||||
google.maps.event.addDomListener(controlUI, 'click', function()
|
||||
{
|
||||
{% if not route.event.map_location %}
|
||||
geocoder = new google.maps.Geocoder();
|
||||
geocoder.region = "de";
|
||||
geocoder.geocode( {"address": "{{ route.event.location }}" }, function(results, status) {
|
||||
if (status == google.maps.GeocoderStatus.OK) {
|
||||
map.setMapTypeId( google.maps.MapTypeId.HYBRID );
|
||||
map.setZoom( 15 );
|
||||
|
||||
map.setCenter( results[0].geometry.location );
|
||||
}
|
||||
});
|
||||
{% else %}
|
||||
var loc = new google.maps.LatLng( {{ route.event.map_location }} );
|
||||
map.setMapTypeId( google.maps.MapTypeId.HYBRID );
|
||||
map.setZoom( 20 );
|
||||
|
||||
map.setCenter( loc );
|
||||
|
||||
{% endif %}
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
var m = $("#map")[0];
|
||||
|
||||
var myOptions = {
|
||||
zoom: 10,
|
||||
mapTypeId: google.maps.MapTypeId.ROAD,
|
||||
zoomControl: false,
|
||||
panControl: false,
|
||||
streetViewControl: false,
|
||||
scrollwheel: false
|
||||
}
|
||||
var directionsService = new google.maps.DirectionsService();
|
||||
var directionsDisplay = new google.maps.DirectionsRenderer();
|
||||
var map = new google.maps.Map(m, myOptions);
|
||||
|
||||
directionsDisplay.setMap( map );
|
||||
|
||||
var request = {
|
||||
origin: "{{route.origin}}",
|
||||
destination: "{{route.destination}}",
|
||||
travelMode: google.maps.DirectionsTravelMode.DRIVING
|
||||
}
|
||||
|
||||
directionsService.route(request, function(response, status) {
|
||||
if (status == google.maps.DirectionsStatus.OK) {
|
||||
directionsDisplay.setDirections(response);
|
||||
|
||||
var leg = response.routes[0].legs[0];
|
||||
|
||||
$("#route_duration").html( leg.duration.text );
|
||||
$("#route_distance").html( leg.distance.text ) ;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var showInfoControlDiv = document.createElement('div');
|
||||
var showInfoControl = new OpenWindowControl(showInfoControlDiv, map);
|
||||
showInfoControlDiv.index = 1;
|
||||
map.controls[google.maps.ControlPosition.TOP_RIGHT].push( showInfoControlDiv );
|
||||
|
||||
var showTargetControlDiv = document.createElement('div');
|
||||
var showTargetControl = new ShowTargetControl(showTargetControlDiv, map);
|
||||
|
||||
showTargetControlDiv.index = 2;
|
||||
map.controls[ google.maps.ControlPosition.TOP_RIGHT ].push(showTargetControlDiv);
|
||||
|
||||
|
||||
|
||||
$("#map_box a").click( function() {
|
||||
$("#map_box").hide();
|
||||
map.setOptions( { scrollwheel: true } );
|
||||
});
|
||||
}
|
||||
);
|
||||
</script>
|
||||
{% endaddtoblock %}
|
||||
|
||||
|
||||
|
||||
|
||||
<div id="concert_route">
|
||||
<div id="map"></div>
|
||||
<div id="map_box" class="row map">
|
||||
<div class="container">
|
||||
<div id="route_info_box" class="span5 box_wrapp">
|
||||
<div class="box_cont">
|
||||
<div class="head">
|
||||
<h4>Nächstes Konzert</h4>
|
||||
|
||||
<!--
|
||||
</div>
|
||||
Nächstes Konzert ist in <br> <em>{{route.event.location}}</em> <br> am {{route.event.date | date:"SHORT_DATE_FORMAT" }} um {{route.event.time | time:"H:i" }} Uhr <br/>
|
||||
{% if route.event.meeting_time %} Treffpunkt ist um {{ route.event.meeting_time | time:"H:i" }} Uhr <br/> {% endif %}
|
||||
|
||||
<table>
|
||||
<tr> <td> Fahrzeit:</td> <td> <span id="route_duration"></span> </td> </tr>
|
||||
<tr> <td> Strecke: </td> <td> <span id="route_distance"></span> </td> </tr>
|
||||
</table>
|
||||
-->
|
||||
<table class="table table-striped table-condensed">
|
||||
<tr><td>Ort: </td> <td> {{route.event.location}} </td> </tr>
|
||||
<tr><td>Datum: </td> <td> {{route.event.date | date:"D, d.m.y" }} </td> </tr>
|
||||
<tr><td>Uhrzeit: </td> <td> {{route.event.time | time:"H:i" }} Uhr </td> </tr>
|
||||
{% if route.event.meeting_time %} <tr><td>Treffen um: </td> <td> {{route.event.meeting_time | time:"H:i" }} Uhr </td> </tr> {% endif %}
|
||||
<tr> <td> Fahrzeit:</td> <td> <span id="route_duration"></span> </td> </tr>
|
||||
<tr> <td> Strecke: </td> <td> <span id="route_distance"></span> </td> </tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<a class="btn" >Schliessen</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{% endif %}
|
||||
Reference in New Issue
Block a user