From 230f1e6a36a8420b605b8e6e0fe8849792e12446 Mon Sep 17 00:00:00 2001 From: Martin Bauer Date: Sun, 22 Sep 2013 11:11:48 +0200 Subject: [PATCH] Addressbook - location field.. has to be refactored --- blechreiz/database.sqlite | Bin 53248 -> 56320 bytes blechreiz/settings.py | 2 +- blechreiz/templates/field.html | 20 +++ blechreiz/urls.py | 6 +- eventplanner/models.py | 5 + .../eventplanner/eventplanning_view.html | 2 - {locpick => location_field}/__init__.py | 0 location_field/forms.py | 28 +++ location_field/media/form.js | 139 +++++++++++++++ location_field/models.py | 40 +++++ location_field/urls.py | 11 ++ location_field/views.py | 1 + location_field/widgets.py | 54 ++++++ locpick/field.py | 93 ---------- locpick/models.py | 0 locpick/settings.py | 6 - .../static/locpick/jquery.location_picker.js | 166 ------------------ locpick/static/locpick/location_picker.css | 7 - locpick/templates/locpick/map.html | 25 --- locpick/templatetags/__init__.py | 0 locpick/templatetags/gmap.py | 28 --- locpick/widget.py | 33 ---- musicians/models.py | 18 +- .../templates/musicians/addressbook.html | 144 +++++++++++++++ musicians/views.py | 21 ++- website/templates/website/base.html | 1 + website/templates/website/mainpage.html | 164 ++++++++--------- website/views.py | 36 ++-- 28 files changed, 587 insertions(+), 463 deletions(-) create mode 100644 blechreiz/templates/field.html rename {locpick => location_field}/__init__.py (100%) mode change 100644 => 100755 create mode 100644 location_field/forms.py create mode 100644 location_field/media/form.js create mode 100755 location_field/models.py create mode 100644 location_field/urls.py create mode 100755 location_field/views.py create mode 100644 location_field/widgets.py delete mode 100644 locpick/field.py delete mode 100644 locpick/models.py delete mode 100644 locpick/settings.py delete mode 100644 locpick/static/locpick/jquery.location_picker.js delete mode 100644 locpick/static/locpick/location_picker.css delete mode 100644 locpick/templates/locpick/map.html delete mode 100644 locpick/templatetags/__init__.py delete mode 100644 locpick/templatetags/gmap.py delete mode 100644 locpick/widget.py create mode 100644 musicians/templates/musicians/addressbook.html diff --git a/blechreiz/database.sqlite b/blechreiz/database.sqlite index 5eece000b5c135117666b8eee59f6d08aab6dca1..4568dc0c6686f7cabef0d6d0404ab7dd46e21ad4 100644 GIT binary patch delta 4618 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 B{zL!( delta 1039 zcma)4T}TvB6uvW`Hlw)Kw(c(duWV+J>(1Su*&T~;32RZbdI<|E*L6)ZopcK+DAbHz zt4mM5ga$=fkn>lIhZ zmy3%Pi>#iZ8re;}ekB{HSq8ie&4|N`K@5^OJ65hlrL;d{Mw?B&sUejJCe1otA25Qo zd~aJrB6%>~v`-V8HdhqjIV+e;l41>RF3+1!4Z#wOCFG;>9kx?!RjX_+r_#OHp}0Ah zPVBaJ)h(38k@}61?>i=Ajq(iYpk!14<_>dtN)-1ms9r4jZS>+jq>Bdc1!)acWn}KeISLnlSbR$KBZo}I3v+@JRAFJpgJsOFq z%Mp|QhNHz?i||ND6@7gP*wHVPb6)Dw1<`-LdZ`^f3~w<`iXY)V8TT8WU|xTNryR)yN)soYD{U=hg}5)8p3Tem`iA5s>BI;RoJe3?tOxF2snn zhLABvyq~E4jpiI9 + +
+ {{ field }} + {% if field.errors %} + {% for error in field.errors %}{{ error }}
{% endfor %}
+ {% endif %} + {% if field.help_text%} +

+ {{ field.help_text|safe }} +

+ {% endif %} +
+ +{% endif %} diff --git a/blechreiz/urls.py b/blechreiz/urls.py index 80bb9bf..b0b995d 100644 --- a/blechreiz/urls.py +++ b/blechreiz/urls.py @@ -2,7 +2,7 @@ from django.conf.urls import patterns, include, url from django.contrib import admin -from musicians.views import MusicianList +from musicians.views import MusicianList, addressbook from musicians.views import user_edit import intern_area.views @@ -17,15 +17,17 @@ from django.conf.urls.static import static admin.autodiscover() urlpatterns = patterns('', - url(r'$^', website.views.home_view), + url(r'$^', website.views.home_view ), url(r'^events/', include( eventplanner.urls.urlpatterns) ), url(r'^admin/', include(admin.site.urls) ), url(r'^admin/doc/', include('django.contrib.admindocs.urls') ), url(r'^musicians/$', MusicianList.as_view() ), url(r'^musicians/(?P[\w]+)$', user_edit ), + url(r'^addressbook/$', addressbook ), url(r'^admin_area/$', intern_area.views.login_site ), url(r'^login/$', website.views.login_view), url(r'^logout/$', website.views.logout_view), url(r'^messages/$', messages.views.message_view ), + url(r'^location_field/', include('location_field.urls')), ) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) \ No newline at end of file diff --git a/eventplanner/models.py b/eventplanner/models.py index 0288522..ed28693 100644 --- a/eventplanner/models.py +++ b/eventplanner/models.py @@ -4,6 +4,8 @@ from django.utils.translation import ugettext as _ from musicians.models import Musician from datetime import datetime +from location_field.models import PlainLocationField + class Event ( models.Model ): @@ -17,11 +19,14 @@ class Event ( models.Model ): title = models.CharField( max_length=40, verbose_name = _("titel") ) type = models.CharField( max_length=6, choices=EVENT_TYPES, default='Reh', verbose_name= _("type") ) location = models.TextField( blank=False, verbose_name=_("location") ) + map_location = PlainLocationField( based_fields = [location], zoom=7 ) desc = models.TextField( blank=True, verbose_name=_("description")) date = models.DateField( verbose_name= _("date") ) time = models.TimeField( null=True, blank=True, verbose_name = _("time") ) meeting_time = models.TimeField( null=True, blank=True, verbose_name = _("meeting_time") ) + + participants = models.ManyToManyField( Musician, through='EventParticipation', verbose_name=_("participants") ) diff --git a/eventplanner/templates/eventplanner/eventplanning_view.html b/eventplanner/templates/eventplanner/eventplanning_view.html index 6f5c9a8..1b191f4 100644 --- a/eventplanner/templates/eventplanner/eventplanning_view.html +++ b/eventplanner/templates/eventplanner/eventplanning_view.html @@ -14,8 +14,6 @@ {% block content %} - - {% addtoblock "js" strip %} {% endaddtoblock %} {% addtoblock "js" %} diff --git a/locpick/__init__.py b/location_field/__init__.py old mode 100644 new mode 100755 similarity index 100% rename from locpick/__init__.py rename to location_field/__init__.py diff --git a/location_field/forms.py b/location_field/forms.py new file mode 100644 index 0000000..4e4f8fe --- /dev/null +++ b/location_field/forms.py @@ -0,0 +1,28 @@ +from django.forms import fields +from location_field.widgets import LocationWidget + + +class PlainLocationField(fields.CharField): + def __init__(self, based_fields=None, zoom=None, default=None, + *args, **kwargs): + kwargs['initial'] = default + + self.widget = LocationWidget(based_fields=based_fields, zoom=zoom, + **kwargs) + + dwargs = { + 'required': True, + 'label': None, + 'initial': None, + 'help_text': None, + 'error_messages': None, + 'show_hidden_initial': False, + } + + for attr in dwargs: + if attr in kwargs: + dwargs[attr] = kwargs[attr] + + super(PlainLocationField, self).__init__(*args, **dwargs) + + diff --git a/location_field/media/form.js b/location_field/media/form.js new file mode 100644 index 0000000..1d03c8e --- /dev/null +++ b/location_field/media/form.js @@ -0,0 +1,139 @@ +($ || django.jQuery)(function($){ + function location_field_load(map, location_based, zoom) + { + var parent = map.parent().parent(); + + var location_map; + + var location_coordinate = parent.find('input[type=text]'); + + function load() { + var point = new google.maps.LatLng(49.340174,10.890595); + + var options = { + mapTypeId: google.maps.MapTypeId.HYBRID + }; + + location_map = new google.maps.Map(map[0], options); + + var initial_position; + + if (location_coordinate.val()) + { + var l = location_coordinate.val().split(/,/); + + if (l.length > 1) + { + initial_position = new google.maps.LatLng(l[0], l[1]); + location_map.setZoom( parseInt(l[2]) ); + } + } + else + { + location_map.setZoom(zoom); + } + + + function savePosition( p ) + { + point = p; + location_coordinate.val(point.lat().toFixed(6) + "," + point.lng().toFixed(6) + "," + location_map.getZoom() ); + } + + var marker = new google.maps.Marker({ + map: location_map, + position: initial_position, + draggable: true + }); + + google.maps.event.addListener(marker, 'dragend', function(mouseEvent) { + savePosition(mouseEvent.latLng); + }); + + google.maps.event.addListener(location_map, 'click', function(mouseEvent){ + marker.setPosition(mouseEvent.latLng); + savePosition(mouseEvent.latLng); + }); + + google.maps.event.addListener(location_map, 'zoom_changed', function(mouseEvent){ + savePosition(point); + }); + + location_based.bindWithDelay("keypress", function() { + + var lstr = []; + location_based.each(function(){ + var b = $(this); + lstr.push(b.val()) + }); + + geocode(lstr.join(','), function(l){ + location_coordinate.val( l.lat()+','+l.lng() ); + }); + + onLocationCoordinateChange(); + }, 2000 ); + + + function onLocationCoordinateChange() + { + var latlng = jQuery(this).val().split(/,/); + if (latlng.length < 2) return; + var latlng = new google.maps.LatLng(latlng[0], latlng[1]); + placeMarker( latlng ); + location_map.setZoom( latlng[2] ); + //geocode_reverse(latlng, function(l){ + // location_coordinate.val(l.lat()+','+l.lng()); + //}); + } + + function placeMarker(location) { + marker.setPosition(location); + location_map.setCenter(location); + savePosition(location); + location_map.panTo(location); + } + + function geocode(address, cb) { + var result; + var geocoder = new google.maps.Geocoder(); + if (geocoder) { + geocoder.geocode({"address": address}, function(results, status) { + if (status == google.maps.GeocoderStatus.OK) { + cb(results[0].geometry.location); + placeMarker(results[0].geometry.location); + } + }); + } + } + /* + function geocode_reverse(location, cb) { + var geocoder = new google.maps.Geocoder(); + if (geocoder) { + geocoder.geocode({"latLng": location}, function(results, status) { + if (status == google.maps.GeocoderStatus.OK) { + cb(results[0].geometry.location); + placeMarker(results[0].geometry.location); + } + }); + } + }*/ + + + placeMarker(initial_position); + } + + load(); + } + + + $('input[data-location-widget]').each(function(){ + var $el = $(this); + + var $map = $($el.attr('data-map')), + $based_fields = $($el.attr('data-based-fields')), + zoom = parseInt($el.attr('data-zoom')); + + location_field_load($map, $based_fields, zoom); + }); +}); diff --git a/location_field/models.py b/location_field/models.py new file mode 100755 index 0000000..4349da9 --- /dev/null +++ b/location_field/models.py @@ -0,0 +1,40 @@ +from django.db.models import CharField + +from location_field import forms + + +class BaseLocationField(object): + def __init__(self, based_fields=[], zoom=2, default=None, *args, **kwargs): + self._based_fields = based_fields + self._zoom = zoom + self._default = default + self.default = default + + def formfield(self, **kwargs): + return super(BaseLocationField, self).formfield( + form_class=self.formfield_class, + based_fields=self._based_fields, + zoom=self._zoom, + default=self._default, + **kwargs) + + +class PlainLocationField(BaseLocationField, CharField): + formfield_class = forms.PlainLocationField + + def __init__(self, based_fields=None, zoom=None, + max_length=63, *args, **kwargs): + + super(PlainLocationField, self).__init__(based_fields=based_fields, + zoom=zoom, *args, **kwargs) + + CharField.__init__(self, max_length=max_length, *args, **kwargs) + + +# south compatibility +try: + from south.modelsinspector import add_introspection_rules + add_introspection_rules([], ["^location_field\.models\.LocationField"]) + add_introspection_rules([], ["^django\.contrib\.gis"]) +except: + pass diff --git a/location_field/urls.py b/location_field/urls.py new file mode 100644 index 0000000..9878cc9 --- /dev/null +++ b/location_field/urls.py @@ -0,0 +1,11 @@ +from django.conf.urls.defaults import patterns + +import os + +app_dir = os.path.dirname(__file__) + +urlpatterns = patterns( + '', + (r'^media/(.*)$', 'django.views.static.serve', { + 'document_root': '%s/media' % app_dir}), +) diff --git a/location_field/views.py b/location_field/views.py new file mode 100755 index 0000000..60f00ef --- /dev/null +++ b/location_field/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/location_field/widgets.py b/location_field/widgets.py new file mode 100644 index 0000000..7774fc7 --- /dev/null +++ b/location_field/widgets.py @@ -0,0 +1,54 @@ +from django.forms import widgets +from django.utils.safestring import mark_safe + + +class LocationWidget(widgets.TextInput): + def __init__(self, attrs=None, based_fields=None, zoom=None, **kwargs): + self.based_fields = based_fields + self.zoom = zoom + super(LocationWidget, self).__init__(attrs) + + def render(self, name, value, attrs=None): + if value is not None: + lat, lng, zoom = value.split(',') + + value = '%s,%s,%d' % ( + float(lat), + float(lng), + float(zoom) + ) + else: + value = '' + + if '-' not in name: + prefix = '' + else: + prefix = name[:name.rindex('-') + 1] + + based_fields = ','.join( + map(lambda f: '#id_' + prefix + f.name, self.based_fields)) + + attrs = attrs or {} + attrs['data-location-widget'] = name + attrs['data-based-fields'] = based_fields + attrs['data-zoom'] = self.zoom + attrs['data-map'] = '#map_' + name + + text_input = super(LocationWidget, self).render(name, value, attrs) + + map_div = u''' +
+ +
+
+''' + return mark_safe(text_input + map_div % {'name': name}) + + class Media: + # Use schemaless URL so it works with both, http and https websites + js = ( + '//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', # jquery + '//maps.google.com/maps/api/js?sensor=false&language=de', + '/static/js/bindWithDelay.js', + '/location_field/media/form.js', + ) diff --git a/locpick/field.py b/locpick/field.py deleted file mode 100644 index 7e595b5..0000000 --- a/locpick/field.py +++ /dev/null @@ -1,93 +0,0 @@ -from django.db import models -from django.template import loader - -from locpick import settings -from locpick.widget import LocationPickerWidget - - -class LocationField(models.CharField): - - def __init__(self, *args, **kwargs): - kwargs['max_length'] = 100 - return super(LocationField, self).__init__(*args, **kwargs) - - def formfield(self, **kwargs): - kwargs['widget'] = LocationPickerWidget - return super(LocationField, self).formfield(**kwargs) - - def contribute_to_class(self, cls, name): - super(LocationField, self).contribute_to_class(cls, name) - setattr(cls, self.name, LocationFieldDescriptor(self)) - - -class LocationFieldDescriptor(object): - - def __init__(self, field): - self.field = field - - def __get__(self, instance=None, owner=None): - if instance is None: - raise AttributeError( - "The '%s' attribute can only be accessed from %s instances." - % (self.field.name, owner.__name__)) - return Map(instance.__dict__[self.field.name]) - - def __set__(self, instance, value): - instance.__dict__[self.field.name] = value - - -class Map(object): - - def __init__(self, value): - self.value = value - self.position = 49.340119, 10.890325 - self.center = 49.340119, 10.890325 - self.zoom = 4 - if value: - values = value.split(',') - self.zoom = int(values.pop()) - values = [str(float(it)) for it in values] - self.position = values[0], values[1] - self.center = values[2], values[3] - - def __str__(self): - return str(self.value) - - def __unicode__(self): - return unicode(self.value) - - def __repr__(self): - return unicode(self) - - def __nonzero__(self): - return bool(self.value) - - def render_map(self, width=settings.DEFAULT_MAP_WIDTH, height=settings.DEFAULT_MAP_HEIGHT): - return loader.render_to_string( - 'locpick/map.html', - { - 'id': id(self), - 'map': self, - 'width': width, - 'height': height, - } - ) - - @property - def external_url(self): - return "http://maps.google.com/?ll=%s,%s&z=%s&q=%s,%s" % ( - self.center[0], - self.center[1], - self.zoom, - self.position[0], - self.position[1], - ) - - - -try: - from south.modelsinspector import add_introspection_rules -except ImportError: - pass -else: - add_introspection_rules([], [r"^locpick\.field\.LocationField"]) diff --git a/locpick/models.py b/locpick/models.py deleted file mode 100644 index e69de29..0000000 diff --git a/locpick/settings.py b/locpick/settings.py deleted file mode 100644 index 87d9120..0000000 --- a/locpick/settings.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.conf import settings - - -DEFAULT_MAP_WIDTH = getattr(settings, 'LOCPICK_DEFAULT_MAP_WIDTH', 600) -DEFAULT_MAP_HEIGHT = getattr(settings, 'LOCPICK_DEFAULT_MAP_HEIGHT', 300) - diff --git a/locpick/static/locpick/jquery.location_picker.js b/locpick/static/locpick/jquery.location_picker.js deleted file mode 100644 index b6ae225..0000000 --- a/locpick/static/locpick/jquery.location_picker.js +++ /dev/null @@ -1,166 +0,0 @@ -//#google.load("maps", "2"); - -/*$(document).unload(function(){ - GUnload(); -}); -*/ - -$(document).ready(function(){ - $("input.location_picker").each(function (i) { - var geocoder = new google.maps.Geocoder(); - var map = $('
'); - var input = this; - map.addClass("location_picker_map"); - map.attr('id', 'location_picker_map'); - $(this).css('display','none'); - var search_field = $(''); - var search_button = $('') - search_field.attr('id', 'location_picker_search') - $(this).parent().append(map); - $(this).parent().append($('
')); - $(this).parent().append(search_field); - $(this).parent().append(search_button); - - - if (this.value.split(',').length == 5) { - values = this.value.split(','); - var position = new google.maps.LatLng(values[0], values[1]); - var center = new google.maps.LatLng(values[2], values[3]); - var zoom = parseInt(values[4]); - } else { - var center = new google.maps.LatLng(49.340119,10.890325); - var position = new google.maps.LatLng(49.340119,10.890325); - var zoom = 17; - this.value = position.lat() - + ',' + position.lng() - + ',' + center.lat() - + ',' + center.lng() - + ',' + zoom; - } - - geocoder.geocode({'latLng': position}, function(results, status) { - if (status == google.maps.GeocoderStatus.OK) { - if (results[0]) { - document.getElementById('location_picker_search').value = results[0].formatted_address ; - } - } - }); - - - - var myOptions = { - zoom: zoom, - center: center, - mapTypeId: google.maps.MapTypeId.HYBRID - }; - var gmap = new google.maps.Map(document.getElementById("location_picker_map"), myOptions); - - if (position != null) { - var marker = new google.maps.Marker({ - position: position, - map: gmap, - }); - } else { - var marker = null; - } - - function geoCode(){ - var address = document.getElementById("location_picker_search").value; - geocoder.geocode( { 'address': address}, function(results, status) { - if (status == google.maps.GeocoderStatus.OK) { - var latLon = results[0].geometry.location; - gmap.setCenter(latLon); - if (marker == null){ - marker = new google.maps.Marker({ - position: latLon, - map: gmap, - }); - } else { - marker.setPosition(latLon); - } - updateInput(); - } else { - alert("Geocode was not successful for the following reason: " + status); - } - }); - }; - search_button.click(function() { - result = geoCode(); - }); - search_field.bind('keydown', function(e) { - var code = (e.keyCode ? e.keyCode : e.which); - if (code == 13) { //Enter keycode - geoCode(); - return false; - } - }); - - function updateInput(){ - if (marker == null){ - return; - } - var pos = marker.getPosition(); - input.value = pos.lat() - + ',' + pos.lng() - + ',' + gmap.getCenter().lat() - + ',' + gmap.getCenter().lng() - + ',' + gmap.getZoom(); - } - google.maps.event.addListener(gmap, 'click', function(event) { - if (marker == null) { - marker = new google.maps.Marker({ - position: event.latLng, - map: gmap, - }); - } else { - marker.setPosition(event.latLng); - } - updateInput(); - }); - - google.maps.event.addListener(gmap, 'center_changed', function(event) { - updateInput(); - }); - google.maps.event.addListener(gmap, 'zoom_changed', function(event) { - updateInput(); - }); - - function HomeControl(controlDiv, gmap) { - - controlDiv.style.padding = '5px'; - - // 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 = 'Click to remove the marker'; - controlDiv.appendChild(controlUI); - - // Set CSS for the control interior - var controlText = document.createElement('DIV'); - controlText.style.fontFamily = 'sans-serif'; - controlText.style.fontSize = '12px'; - controlText.style.paddingLeft = '4px'; - controlText.style.paddingRight = '4px'; - controlText.innerHTML = 'Clear'; - controlUI.appendChild(controlText); - - // Setup the click event listeners: simply set the map to Chicago - google.maps.event.addDomListener(controlUI, 'click', function() { - if (marker != null){ - marker.setMap(null); - marker = null; - input.value = ''; - } - }); - } - var homeControlDiv = document.createElement('DIV'); - var homeControl = new HomeControl(homeControlDiv, gmap); - - homeControlDiv.index = 1; - gmap.controls[google.maps.ControlPosition.TOP_RIGHT].push(homeControlDiv); - }); -}); diff --git a/locpick/static/locpick/location_picker.css b/locpick/static/locpick/location_picker.css deleted file mode 100644 index 90c30ee..0000000 --- a/locpick/static/locpick/location_picker.css +++ /dev/null @@ -1,7 +0,0 @@ -.location_picker_map { - width: 600px; - height: 400px; - border: 1px solid black; - padding: 2px; - display: inline-block; -} diff --git a/locpick/templates/locpick/map.html b/locpick/templates/locpick/map.html deleted file mode 100644 index bdf4210..0000000 --- a/locpick/templates/locpick/map.html +++ /dev/null @@ -1,25 +0,0 @@ -
- - - -
diff --git a/locpick/templatetags/__init__.py b/locpick/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/locpick/templatetags/gmap.py b/locpick/templatetags/gmap.py deleted file mode 100644 index 2559453..0000000 --- a/locpick/templatetags/gmap.py +++ /dev/null @@ -1,28 +0,0 @@ -from django import template - -from locpick import settings - - -register = template.Library() - - -class LocpickNode(template.Node): - def __init__(self, field, width=settings.DEFAULT_MAP_WIDTH, height=settings.DEFAULT_MAP_HEIGHT): - self.field_name = field - self.width = width - self.height = height - - def render(self, context): - field = template.Variable(self.field_name).resolve(context) - return field.render_map(width=self.width, height=self.height) - - -@register.tag -def gmap(parser, token): - bits = token.split_contents() - if len(bits) == 2: - return LocpickNode(field=bits[1]) - elif len(bits) == 4: - return LocpickNode(field=bits[1], width=bits[2], height=bits[3]) - else: - raise template.TemplateSyntaxError('{% locpick instance.location_field %} or {% locpick instance.location_field WIDTH HEIGHT %}') diff --git a/locpick/widget.py b/locpick/widget.py deleted file mode 100644 index b1c46c5..0000000 --- a/locpick/widget.py +++ /dev/null @@ -1,33 +0,0 @@ -from django import forms -from django.conf import settings - - -if hasattr(settings, 'LOCPICK_STATIC_URL'): - STATIC_URL = settings.LOCPICK_STATIC_URL -else: - STATIC_URL = settings.STATIC_URL + 'locpick/' - - -class LocationPickerWidget(forms.TextInput): - class Media: - css = { - 'all': ( - STATIC_URL + 'location_picker.css', - ) - } - js = ( - 'http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js', - 'http://maps.google.com/maps/api/js?sensor=false', - STATIC_URL + 'jquery.location_picker.js', - ) - - def __init__(self, language=None, attrs=None): - self.language = language or settings.LANGUAGE_CODE[:2] - super(LocationPickerWidget, self).__init__(attrs=attrs) - - def render(self, name, value, attrs=None): - if None == attrs: - attrs = {} - attrs['class'] = 'location_picker' - return super(LocationPickerWidget, self).render(name, value, attrs) - diff --git a/musicians/models.py b/musicians/models.py index c223d58..34756e1 100644 --- a/musicians/models.py +++ b/musicians/models.py @@ -7,7 +7,7 @@ import os INSTRUMENTS = ( ('TR', _('Trumpet') ), ('TRB', _('Trombone') ), - ('EUPH',_('Euphonium') ), + ('HRN',_('Horn') ), ('TUBA',_('Tuba') ) ) @@ -16,14 +16,20 @@ def musicianPictureName( musician, originalName ): fileExtension = os.path.splitext(originalName)[1] return "user_images/" + musician.user.username + fileExtension +def musicianSmallPictureName( musician, originalName ): + fileExtension = os.path.splitext(originalName)[1] + return "user_images/" + musician.user.username + "_thumb" + fileExtension + class Musician( models.Model ): # Link to user object, contains first name and last name user = models.OneToOneField( User, verbose_name=_("user") ) - # Properties - image = models.ImageField( upload_to = musicianPictureName, verbose_name=_("image") ) + image = models.ImageField( upload_to = musicianPictureName, verbose_name=_("image") ) + small_image = models.ImageField( upload_to = musicianSmallPictureName, verbose_name = _("circular thumbnail") ) + + # Properties instrument = models.CharField( max_length=4, choices=INSTRUMENTS, blank=True, verbose_name=_("instrument") ) birthday = models.DateField( null=True, verbose_name=_("birthday") ) @@ -36,7 +42,13 @@ class Musician( models.Model ): phone_mobile = models.CharField( max_length=18, blank=True, verbose_name=_("phone_mobile") ) phone_work = models.CharField( max_length=18, blank=True, verbose_name=_("phone_work") ) + @property + def isDeepBrass(self): + return self.instrument == 'TRB' or self.instrument == "EUPH" or self.instrument == "TUBA" or self.instrument == "HRN" + @property + def isHighBrass(self): + return self.instrument == 'TR' public_description = models.TextField( blank=True, verbose_name=_("public_description") ) diff --git a/musicians/templates/musicians/addressbook.html b/musicians/templates/musicians/addressbook.html new file mode 100644 index 0000000..13868d5 --- /dev/null +++ b/musicians/templates/musicians/addressbook.html @@ -0,0 +1,144 @@ +{% extends "website/base.html" %} + + +{% load sekizai_tags staticfiles %} + + +{% block feature_slider %} +{% endblock %} + + +{% block navbar_options %} navbar navbar-inverse navbar-static-top {% endblock %} + + +{% block content %} + + +{% addtoblock "css" strip %}{% endaddtoblock %} + +{% addtoblock "css" %} + +{% endaddtoblock %} + + +{% addtoblock "js" strip %} {% endaddtoblock %} + + +{% addtoblock "js" %} + + +{% endaddtoblock %} + + +
+
+
+

Adressbuch

+
+ +
+
+
+ +
+
+
+ +
+
+ + +
+
+
+
+ + +{% endblock %} + diff --git a/musicians/views.py b/musicians/views.py index e8c326d..911b1c9 100644 --- a/musicians/views.py +++ b/musicians/views.py @@ -12,7 +12,7 @@ class MusicianList( ListView): model = Musician -class UserEditForm(forms.ModelForm): +class UserEditForm( forms.ModelForm ): email = forms.EmailField() @@ -43,7 +43,6 @@ class UserEditForm(forms.ModelForm): model = Musician exclude = [ 'user','image', 'instrument' ] #fields = '__all__' - def user_edit( request, username ): @@ -66,4 +65,20 @@ class MusicianUpdate( UpdateView ): model = Musician #fields = [] template_name = "musicians/musician_edit.html" - success_url = '/books/' \ No newline at end of file + success_url = '/books/' + + +def addressbook( request ): + context = dict() + context['musicians'] = Musician.objects.all() + + return render( request, 'musicians/addressbook.html', context ) + + + + + + + + + diff --git a/website/templates/website/base.html b/website/templates/website/base.html index 3f93b0b..be81312 100644 --- a/website/templates/website/base.html +++ b/website/templates/website/base.html @@ -28,6 +28,7 @@ {% addtoblock "js" strip %} {% endaddtoblock %} {% addtoblock "js" strip %} {% endaddtoblock %} {% addtoblock "js" strip %} {% endaddtoblock %} +{% addtoblock "js" strip %} {% endaddtoblock %} {% addtoblock "js" %} diff --git a/website/templates/website/mainpage.html b/website/templates/website/mainpage.html index 7a6de18..533da2b 100644 --- a/website/templates/website/mainpage.html +++ b/website/templates/website/mainpage.html @@ -75,87 +75,89 @@ {% addtoblock "css" strip %}{% endaddtoblock %} {% addtoblock "css" strip %}{% endaddtoblock %} + {% if event %} + + {% addtoblock "js" %} + + {% endaddtoblock %} + + + +
+
+
+
+

Der nächste Termin:

+

+ {{event.title}} ist am {{event.date}} um {{event.displaytime | time:"H:i" }} in {{event.location}} + +
+ {% if participation == "?" %} + Du hast dich noch nicht für diesen Termin eingetragen! + {% elif participation == "Yes" %} + Du hast für diesen Termin zugesagt. + {% elif participation == "No" %} + Du hast für diesen Termin abgesagt. + {%endif %} +

+
+
+
+
+ +
+

Sekunden

+
+
+
+ +
+

Minuten

+
+
+
+ +
+

Stunden

+
+
+
+ +
+

Tage

+
+ +
+
+
+
+ {% endif %} - {% addtoblock "js" %} - - {% endaddtoblock %} - - - -
-
-
-
-

Der nächste Termin:

-

- {{event.title}} ist am {{event.date}} um {{event.displaytime | time:"H:i" }} in {{event.location}} - -
- {% if participation == "?" %} - Du hast dich noch nicht für diesen Termin eingetragen! - {% elif participation == "Yes" %} - Du hast für diesen Termin zugesagt. - {% elif participation == "No" %} - Du hast für diesen Termin abgesagt. - {%endif %} -

-
-
-
-
- -
-

Sekunden

-
-
-
- -
-

Minuten

-
-
-
- -
-

Stunden

-
-
-
- -
-

Tage

-
- -
-
-
-
- {% endblock %} diff --git a/website/views.py b/website/views.py index 21dfc57..308ee6d 100644 --- a/website/views.py +++ b/website/views.py @@ -7,26 +7,35 @@ from django.core.urlresolvers import reverse from django.http import HttpResponse from django.utils import simplejson +from django.contrib.auth.decorators import login_required from eventplanner.models import Event, EventParticipation from datetime import datetime +@login_required def home_view(request): - events = Event.objects.filter( date__gte = datetime.now() ).order_by('date')[:1] context = dict() - - - part = EventParticipation.objects.filter( musician__user = request.user ).filter( event = events[0] ) - - eventTime = datetime( events[0].date.year, events[0].date.month, events[0].date.day, - events[0].displaytime.hour, events[0].displaytime.minute ) - - context['hasParticipationSetForAllEvents'] = EventParticipation.hasUserSetParticipationForAllEvents( request.user) - context['event'] = events[0] - context['epoch'] = int( (eventTime - datetime.now() ).total_seconds() * 1000 ) - context['participation'] = part[0].status + + events = Event.objects.filter( date__gte = datetime.now() ).order_by('date')[:1] + if ( len(events) > 0 ): + print "len(events): " + str( len(events )) + nextEvent = events[0] + part = EventParticipation.objects.filter( musician__user = request.user ).filter( event = nextEvent ) + + eventTime = datetime( events[0].date.year, events[0].date.month, events[0].date.day, + events[0].displaytime.hour, events[0].displaytime.minute ) + + context['hasParticipationSetForAllEvents'] = EventParticipation.hasUserSetParticipationForAllEvents( request.user) + context['event'] = events[0] + + context['epoch'] = int( (eventTime - datetime.now() ).total_seconds() * 1000 ) + context['participation'] = part[0].status + else: + context['hasParticipationSetForAllEvents'] = True + + return render( request, 'website/mainpage.html', context ) @@ -48,7 +57,8 @@ def login_view(request): if not request.POST.get('remember', None): request.session.set_expiry( 0 ) login(request, user) - result['redirect'] = reverse( home_view ) + #result['redirect'] = reverse( home_view ) + result['redirect'] = "/" else: result['err'] = "Dein Account wurde deaktiviert." # Return a 'disabled account' error message