Compare commits
	
		
			72 Commits
		
	
	
		
			0.1.3
			...
			feature/33
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| a22c988e94 | |||
| 7f2283325c | |||
| 6b7c71ef30 | |||
| 067bf36118 | |||
| 9eef044af9 | |||
| a4780a22f2 | |||
| 0d1d829abe | |||
| 59cfa82ce9 | |||
| d47c85795c | |||
| 8e80614eee | |||
| 6a1e2d975b | |||
| c5f6355f19 | |||
| dac63e99ba | |||
| 9f369456d5 | |||
| 011a58f6b3 | |||
| 67ce6cb50b | |||
| 5df7cc5ec6 | |||
| e242dc4add | |||
| 86cc7f23fe | |||
| f73fa616d0 | |||
| 629a609ff5 | |||
| 04fe93c7bb | |||
| 3eaa186b66 | |||
| b42be489dc | |||
| cc59254ba4 | |||
| 67a6517716 | |||
| 0f5474c2d3 | |||
| 17e71b71d4 | |||
| b1aa4473e9 | |||
| 871acd1dce | |||
| 14ca45d111 | |||
| c71fe4cf2d | |||
| 7359bf5fab | |||
| 4f0182fc3e | |||
| 30f259fb4d | |||
| 53f89caef5 | |||
| 3855fb28d7 | |||
| 3a20a60f05 | |||
| 648264c9fc | |||
| dc79b9d05c | |||
| a7c8848fd6 | |||
| b845cc054a | |||
| 07ea2f164c | |||
| b0396f5223 | |||
| 88bffbef8e | |||
| 2022a924c4 | |||
| d5827b2006 | |||
| a9013d9673 | |||
| 0c38ca9a15 | |||
| 734d09df90 | |||
| e601b9bf6b | |||
| 6f6bd6376d | |||
| dc2a703c39 | |||
| 063777ece4 | |||
| 4675e5814f | |||
| 35e0f912fe | |||
| 07fe1bc3ca | |||
| 4a43a4bf37 | |||
| 61cf148417 | |||
| d547ee9db3 | |||
| c7b699f615 | |||
| 86f95a5dd0 | |||
| 916c4b80f7 | |||
| b31dc9fc5f | |||
| 8f048369bf | |||
| f974469996 | |||
| dbbd7b0802 | |||
| d04e986419 | |||
| cbbda88850 | |||
| 981c440ce3 | |||
| c7368f5c44 | |||
| abca946883 | 
@@ -6,6 +6,9 @@ The software is currently in early development status, neither scope, datamodel(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
We value privacy as a whole, all resources the frontend requires will be shipped with lostplace's distribution. We also try to minimize the use of JavaScript as far as we can and try to offer JS-less alternatives where we can.
 | 
					We value privacy as a whole, all resources the frontend requires will be shipped with lostplace's distribution. We also try to minimize the use of JavaScript as far as we can and try to offer JS-less alternatives where we can.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Contact
 | 
				
			||||||
 | 
					If you run into any issues, have any questions or If you are interested in this project in general, feel free to get in touch with us via [reverend@reverend2048.de](mailto:reverend@reverend2048.de), we do speak English and German.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Features
 | 
					## Features
 | 
				
			||||||
- Manage lost places with lots of useful information.
 | 
					- Manage lost places with lots of useful information.
 | 
				
			||||||
- OSM-Maps
 | 
					- OSM-Maps
 | 
				
			||||||
@@ -146,7 +149,3 @@ Before making the django instance public, you should tweak the config `settings.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Run `django_lostplaces/manage.py collectstatic` you should be ready to go.
 | 
					Run `django_lostplaces/manage.py collectstatic` you should be ready to go.
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Contact
 | 
					 | 
				
			||||||
If you run into any issues, have any questions or If you are interested in this project in general, feel free to get in touch with us via [reverend@reverend2048.de](mailto:reverend@reverend2048.de), we do speak English and German.
 | 
					 | 
				
			||||||
@@ -9,8 +9,6 @@ from django.contrib.auth.admin import UserAdmin
 | 
				
			|||||||
from django.utils import timezone
 | 
					from django.utils import timezone
 | 
				
			||||||
from lostplaces.models import *
 | 
					from lostplaces.models import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lostplaces.forms import ExplorerCreationForm, ExplorerChangeForm
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Register your models here.
 | 
					# Register your models here.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VoucherAdmin(admin.ModelAdmin):
 | 
					class VoucherAdmin(admin.ModelAdmin):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
 | 
					from django.shortcuts import redirect
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_all_subclasses(cls):
 | 
					def get_all_subclasses(cls):
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    Gets all subclasses recursively, does not contain
 | 
					    Gets all subclasses recursively, does not contain
 | 
				
			||||||
@@ -9,3 +11,15 @@ def get_all_subclasses(cls):
 | 
				
			|||||||
            subclass_list.append(subclass)
 | 
					            subclass_list.append(subclass)
 | 
				
			||||||
        subclass_list += get_all_subclasses(subclass)
 | 
					        subclass_list += get_all_subclasses(subclass)
 | 
				
			||||||
    return subclass_list
 | 
					    return subclass_list
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					def redirect_referer_or(request, url='/'):
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    Returns a django redirect to the requests referer,
 | 
				
			||||||
 | 
					    if there is no referer the redirect will poin to the given url
 | 
				
			||||||
 | 
					    Default url is /
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					    referer = request.META.get('HTTP_REFERER')  
 | 
				
			||||||
 | 
					    if referer is not None:
 | 
				
			||||||
 | 
					        return redirect(referer)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return redirect(url)
 | 
				
			||||||
@@ -8,12 +8,12 @@ from django.db import models
 | 
				
			|||||||
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
 | 
					from django.contrib.auth.forms import UserCreationForm, UserChangeForm
 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
from django.utils.translation import ugettext_lazy as _
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
from lostplaces.models import Place, PlaceImage, Voucher
 | 
					from lostplaces.models import Place, PlaceImage, Voucher, Explorer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ExplorerCreationForm(UserCreationForm):
 | 
					class SignupVoucherForm(UserCreationForm):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = User
 | 
					        model = User
 | 
				
			||||||
        fields = ('username', 'email')
 | 
					        fields = ('username', 'email', 'first_name', 'last_name')
 | 
				
			||||||
    voucher = forms.CharField(
 | 
					    voucher = forms.CharField(
 | 
				
			||||||
        max_length=30,
 | 
					        max_length=30,
 | 
				
			||||||
        help_text=_('The Voucher you got from an administrator')
 | 
					        help_text=_('The Voucher you got from an administrator')
 | 
				
			||||||
@@ -35,16 +35,47 @@ class ExplorerCreationForm(UserCreationForm):
 | 
				
			|||||||
        fetched_voucher.delete()
 | 
					        fetched_voucher.delete()
 | 
				
			||||||
        return True
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ExplorerChangeForm(UserChangeForm):
 | 
					class ExplorerUserChangeForm(UserChangeForm):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = User
 | 
					        model = User
 | 
				
			||||||
        fields = ('username', 'email')
 | 
					        fields = [ 'username', 'first_name', 'last_name', 'email' ]
 | 
				
			||||||
 | 
					    ''' Hide password hint.'''
 | 
				
			||||||
 | 
					    password = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ''' Display username, but display it non-editable and not required. '''
 | 
				
			||||||
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					        self.fields['username'].required = False
 | 
				
			||||||
 | 
					        self.fields['username'].help_text = None
 | 
				
			||||||
 | 
					        self.fields['username'].widget.attrs['disabled'] = 'disabled'
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def clean_username(self):
 | 
				
			||||||
 | 
					        # As shown in the above answer.
 | 
				
			||||||
 | 
					        instance = getattr(self, 'instance', None)
 | 
				
			||||||
 | 
					        if instance:
 | 
				
			||||||
 | 
					            return instance.username
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return self.cleaned_data.get('username', None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ExplorerChangeForm(forms.ModelForm):
 | 
				
			||||||
 | 
					    class Meta:
 | 
				
			||||||
 | 
					        model = Explorer
 | 
				
			||||||
 | 
					        fields = '__all__'
 | 
				
			||||||
 | 
					        exclude = ['user', 'favorite_places']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlaceForm(forms.ModelForm):
 | 
					class PlaceForm(forms.ModelForm):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        model = Place
 | 
					        model = Place
 | 
				
			||||||
        fields = '__all__'
 | 
					        fields = '__all__'
 | 
				
			||||||
        exclude = ['submitted_by']
 | 
					        exclude = ['submitted_by', 'latitude', 'longitute']
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    latitude = forms.IntegerField(
 | 
				
			||||||
 | 
					        widget=forms.NumberInput(attrs={'min':-90,'max': 90,'type': 'number'})
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    longitude = forms.IntegerField(
 | 
				
			||||||
 | 
					        widget=forms.NumberInput(attrs={'min':-180,'max': 180,'type': 'number'})
 | 
				
			||||||
 | 
					    )    
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
class PlaceImageForm(forms.ModelForm):
 | 
					class PlaceImageForm(forms.ModelForm):
 | 
				
			||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ msgid ""
 | 
				
			|||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Project-Id-Version: PACKAGE VERSION\n"
 | 
					"Project-Id-Version: PACKAGE VERSION\n"
 | 
				
			||||||
"Report-Msgid-Bugs-To: \n"
 | 
					"Report-Msgid-Bugs-To: \n"
 | 
				
			||||||
"POT-Creation-Date: 2020-10-11 21:53+0200\n"
 | 
					"POT-Creation-Date: 2020-12-25 16:04+0100\n"
 | 
				
			||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
					"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
				
			||||||
"Last-Translator: Commander1024 <commander@commander1024.de>\n"
 | 
					"Last-Translator: Commander1024 <commander@commander1024.de>\n"
 | 
				
			||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
					"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
				
			||||||
@@ -30,7 +30,7 @@ msgstr "Ungültiger Voucher"
 | 
				
			|||||||
msgid "Expired voucher"
 | 
					msgid "Expired voucher"
 | 
				
			||||||
msgstr "Abgelaufener Voucher"
 | 
					msgstr "Abgelaufener Voucher"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models/abstract_models.py:29
 | 
					#: models/abstract_models.py:29 templates/explorer/profile.html:31
 | 
				
			||||||
msgid "Name"
 | 
					msgid "Name"
 | 
				
			||||||
msgstr "Name"
 | 
					msgstr "Name"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -74,6 +74,22 @@ msgstr "Adresse (URL)"
 | 
				
			|||||||
msgid "link text"
 | 
					msgid "link text"
 | 
				
			||||||
msgstr "Linktext"
 | 
					msgstr "Linktext"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: models/models.py:47
 | 
				
			||||||
 | 
					msgid "Biography"
 | 
				
			||||||
 | 
					msgstr "Beschreibung"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: models/models.py:48
 | 
				
			||||||
 | 
					msgid "Describe yourself, your preferences, etc. in a few sentences."
 | 
				
			||||||
 | 
					msgstr "Beschreibe Dich selbst, Deine Vorlieben, usw. in ein paar Sätzen."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: models/models.py:56
 | 
				
			||||||
 | 
					msgid "Profile image"
 | 
				
			||||||
 | 
					msgstr "Profilbild"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: models/models.py:57
 | 
				
			||||||
 | 
					msgid "Optional profile image for display in Explorer profile"
 | 
				
			||||||
 | 
					msgstr "Optionales Profilbild zur Anzeige im Explorerprofil"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: models/place.py:21
 | 
					#: models/place.py:21
 | 
				
			||||||
msgid "Location"
 | 
					msgid "Location"
 | 
				
			||||||
msgstr "Ort"
 | 
					msgstr "Ort"
 | 
				
			||||||
@@ -110,38 +126,92 @@ msgstr "Du wirst in 5 Sekunden weitergeleitet"
 | 
				
			|||||||
msgid "Go Back"
 | 
					msgid "Go Back"
 | 
				
			||||||
msgstr "Zurück"
 | 
					msgstr "Zurück"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile.html:41
 | 
				
			||||||
 | 
					msgid "E-mail"
 | 
				
			||||||
 | 
					msgstr "E-Mail"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile.html:52
 | 
				
			||||||
 | 
					msgid "Joined"
 | 
				
			||||||
 | 
					msgstr "Beigetreten"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile.html:60
 | 
				
			||||||
 | 
					#, fuzzy
 | 
				
			||||||
 | 
					#| msgid "All Places"
 | 
				
			||||||
 | 
					msgid "Places"
 | 
				
			||||||
 | 
					msgstr "Alle Places"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile.html:68
 | 
				
			||||||
 | 
					msgid "Place assets"
 | 
				
			||||||
 | 
					msgstr ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile.html:76
 | 
				
			||||||
 | 
					#, fuzzy
 | 
				
			||||||
 | 
					#| msgid "Edit Explorer profile"
 | 
				
			||||||
 | 
					msgid "Edit Profile"
 | 
				
			||||||
 | 
					msgstr "Explorerprofil bearbeiten"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile.html:87
 | 
				
			||||||
 | 
					msgid "Favorite places"
 | 
				
			||||||
 | 
					msgstr "Favoriten"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile.html:103
 | 
				
			||||||
 | 
					msgid "Places submitted by"
 | 
				
			||||||
 | 
					msgstr "Places hinzugefügt von"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile.html:118
 | 
				
			||||||
 | 
					msgid "Images submitted by"
 | 
				
			||||||
 | 
					msgstr "Bilder hinzugefügt von"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile.html:140
 | 
				
			||||||
 | 
					msgid "Photo albums submitted by"
 | 
				
			||||||
 | 
					msgstr "Fotoalben hinzugefügt von"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile_update.html:6
 | 
				
			||||||
 | 
					#: templates/explorer/profile_update.html:12
 | 
				
			||||||
 | 
					msgid "Edit Explorer profile"
 | 
				
			||||||
 | 
					msgstr "Explorerprofil bearbeiten"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/explorer/profile_update.html:48
 | 
				
			||||||
 | 
					#: templates/place/place_update.html:42
 | 
				
			||||||
 | 
					msgid "Update"
 | 
				
			||||||
 | 
					msgstr "Aktualisieren"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/global.html:32
 | 
					#: templates/global.html:32
 | 
				
			||||||
msgid "Logout"
 | 
					msgid "Logout"
 | 
				
			||||||
msgstr "Ausloggen"
 | 
					msgstr "Ausloggen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/global.html:34
 | 
					#: templates/global.html:33
 | 
				
			||||||
 | 
					msgid "Profile"
 | 
				
			||||||
 | 
					msgstr "Profil"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/global.html:35
 | 
				
			||||||
msgid "Admin"
 | 
					msgid "Admin"
 | 
				
			||||||
msgstr "Admin"
 | 
					msgstr "Admin"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/global.html:39 templates/registration/login.html:4
 | 
					#: templates/global.html:40 templates/registration/login.html:4
 | 
				
			||||||
#: templates/registration/login.html:10 templates/registration/login.html:23
 | 
					#: templates/registration/login.html:10 templates/registration/login.html:23
 | 
				
			||||||
msgid "Login"
 | 
					msgid "Login"
 | 
				
			||||||
msgstr "Anmelden"
 | 
					msgstr "Anmelden"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/global.html:40 templates/registration/login.html:29
 | 
					#: templates/global.html:41 templates/registration/login.html:29
 | 
				
			||||||
#: templates/signup.html:6 templates/signup.html:12 templates/signup.html:41
 | 
					#: templates/signup.html:6 templates/signup.html:12 templates/signup.html:49
 | 
				
			||||||
msgid "Sign up"
 | 
					msgid "Sign up"
 | 
				
			||||||
msgstr "Registrieren"
 | 
					msgstr "Registrieren"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/global.html:50 templates/home.html:10
 | 
					#: templates/global.html:51 templates/home.html:10
 | 
				
			||||||
msgid "Home"
 | 
					msgid "Home"
 | 
				
			||||||
msgstr "Startseite"
 | 
					msgstr "Startseite"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/global.html:51
 | 
					#: templates/global.html:52
 | 
				
			||||||
msgid "UrBex Codex"
 | 
					msgid "UrBex Codex"
 | 
				
			||||||
msgstr "UrBex Codex"
 | 
					msgstr "UrBex Codex"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/global.html:56 templates/place/place_create.html:5
 | 
					#: templates/global.html:57 templates/place/place_create.html:5
 | 
				
			||||||
#: templates/place/place_create.html:10
 | 
					#: templates/place/place_create.html:10
 | 
				
			||||||
msgid "Create place"
 | 
					msgid "Create place"
 | 
				
			||||||
msgstr "Place erstellen"
 | 
					msgstr "Place erstellen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/global.html:57
 | 
					#: templates/global.html:58
 | 
				
			||||||
msgid "All places"
 | 
					msgid "All places"
 | 
				
			||||||
msgstr "Alle Places"
 | 
					msgstr "Alle Places"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -194,6 +264,14 @@ msgstr "Abschicken"
 | 
				
			|||||||
msgid "Cancel"
 | 
					msgid "Cancel"
 | 
				
			||||||
msgstr "Abbrechen"
 | 
					msgstr "Abbrechen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/partials/icons/place_favorite.html:6
 | 
				
			||||||
 | 
					msgid "Remove from favorites"
 | 
				
			||||||
 | 
					msgstr "Aus den Favoriten entfernen"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: templates/partials/icons/place_favorite.html:10
 | 
				
			||||||
 | 
					msgid "Save as favorite"
 | 
				
			||||||
 | 
					msgstr "In den Favoriten speichern"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/partials/nav/footer.html:64
 | 
					#: templates/partials/nav/footer.html:64
 | 
				
			||||||
msgid "Made by"
 | 
					msgid "Made by"
 | 
				
			||||||
msgstr "Erstellt von"
 | 
					msgstr "Erstellt von"
 | 
				
			||||||
@@ -318,10 +396,6 @@ msgstr "Alle Places"
 | 
				
			|||||||
msgid "Our lost places"
 | 
					msgid "Our lost places"
 | 
				
			||||||
msgstr "Unsere Lost Places"
 | 
					msgstr "Unsere Lost Places"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: templates/place/place_update.html:42
 | 
					 | 
				
			||||||
msgid "Update"
 | 
					 | 
				
			||||||
msgstr "Aktualisieren"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#: templates/place_image/place_image_create.html:7
 | 
					#: templates/place_image/place_image_create.html:7
 | 
				
			||||||
msgid "Submit images to a place"
 | 
					msgid "Submit images to a place"
 | 
				
			||||||
msgstr "Bilder zu einem Place hinzufügen"
 | 
					msgstr "Bilder zu einem Place hinzufügen"
 | 
				
			||||||
@@ -334,6 +408,16 @@ msgstr "Noch kein Konto?"
 | 
				
			|||||||
msgid "Please login to proceed"
 | 
					msgid "Please login to proceed"
 | 
				
			||||||
msgstr "Bitte log Dich ein um fortzufahren"
 | 
					msgstr "Bitte log Dich ein um fortzufahren"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: views/explorer_views.py:78
 | 
				
			||||||
 | 
					#, fuzzy
 | 
				
			||||||
 | 
					#| msgid "Successfully updated place"
 | 
				
			||||||
 | 
					msgid "Successfully updated Explorer profile"
 | 
				
			||||||
 | 
					msgstr "Place erfolgreich aktualisiert"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: views/explorer_views.py:84 views/place_views.py:105
 | 
				
			||||||
 | 
					msgid "Please fill in all required fields."
 | 
				
			||||||
 | 
					msgstr "Bitte füll alle benötigten Felder aus."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views/place_image_views.py:26
 | 
					#: views/place_image_views.py:26
 | 
				
			||||||
msgid "Image(s) submitted successfully"
 | 
					msgid "Image(s) submitted successfully"
 | 
				
			||||||
msgstr "Bild(er) erfolgreich hinzugefügt"
 | 
					msgstr "Bild(er) erfolgreich hinzugefügt"
 | 
				
			||||||
@@ -358,10 +442,6 @@ msgstr "Du darfst diesen Place nicht bearbeiten"
 | 
				
			|||||||
msgid "Successfully created place"
 | 
					msgid "Successfully created place"
 | 
				
			||||||
msgstr "Place erfolgreich erstellt"
 | 
					msgstr "Place erfolgreich erstellt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: views/place_views.py:105
 | 
					 | 
				
			||||||
msgid "Please fill in all required fields."
 | 
					 | 
				
			||||||
msgstr "Bitte füll alle benötigten Felder aus."
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#: views/place_views.py:112
 | 
					#: views/place_views.py:112
 | 
				
			||||||
msgid "Successfully deleted place"
 | 
					msgid "Successfully deleted place"
 | 
				
			||||||
msgstr "Place erfolgreich gelöscht"
 | 
					msgstr "Place erfolgreich gelöscht"
 | 
				
			||||||
@@ -385,3 +465,8 @@ msgstr "Fotoalbum-Link gelöscht"
 | 
				
			|||||||
#: views/views.py:60
 | 
					#: views/views.py:60
 | 
				
			||||||
msgid "You are not allowed to edit this photo album link"
 | 
					msgid "You are not allowed to edit this photo album link"
 | 
				
			||||||
msgstr "Du darfst diesen Fotoalbum-Link nicht bearbeiten"
 | 
					msgstr "Du darfst diesen Fotoalbum-Link nicht bearbeiten"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#, fuzzy
 | 
				
			||||||
 | 
					#~| msgid "Filename(s)"
 | 
				
			||||||
 | 
					#~ msgid "Filename"
 | 
				
			||||||
 | 
					#~ msgstr "Dateiname(n)"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,7 +65,7 @@ class Migration(migrations.Migration):
 | 
				
			|||||||
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
					                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
 | 
				
			||||||
                ('submitted_when', models.DateTimeField(auto_now_add=True, null=True)),
 | 
					                ('submitted_when', models.DateTimeField(auto_now_add=True, null=True)),
 | 
				
			||||||
                ('description', models.TextField(blank=True)),
 | 
					                ('description', models.TextField(blank=True)),
 | 
				
			||||||
                ('filename', easy_thumbnails.fields.ThumbnailerImageField(upload_to=lostplaces.models.place.generate_image_upload_path)),
 | 
					                ('filename', easy_thumbnails.fields.ThumbnailerImageField(upload_to=lostplaces.models.place.generate_place_image_filename)),
 | 
				
			||||||
                ('place', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='placeimages', to='lostplaces.place')),
 | 
					                ('place', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='placeimages', to='lostplaces.place')),
 | 
				
			||||||
                ('submitted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='placeimages', to='lostplaces.explorer')),
 | 
					                ('submitted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='placeimages', to='lostplaces.explorer')),
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ from django.db import migrations, models
 | 
				
			|||||||
class Migration(migrations.Migration):
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dependencies = [
 | 
					    dependencies = [
 | 
				
			||||||
        ('lostplaces', '0002_reomve_vouchers'),
 | 
					        ('lostplaces', '0002_remove_vouchers'),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    operations = [
 | 
					    operations = [
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										118
									
								
								django_lostplaces/lostplaces/migrations/0004_gory_fix.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								django_lostplaces/lostplaces/migrations/0004_gory_fix.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
				
			|||||||
 | 
					# Generated by Django 3.1.4 on 2020-12-25 16:02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import django.core.validators
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					import django.db.models.deletion
 | 
				
			||||||
 | 
					import easy_thumbnails.fields
 | 
				
			||||||
 | 
					from lostplaces.models.models import generate_profile_image_filename
 | 
				
			||||||
 | 
					from lostplaces.models.place import generate_place_image_filename
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('lostplaces', '0003_voucher'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='explorer',
 | 
				
			||||||
 | 
					            name='bio',
 | 
				
			||||||
 | 
					            field=models.TextField(blank=True, help_text='Describe yourself, your preferences, etc. in a few sentences.', null=True, verbose_name='Biography / Description'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					#        migrations.AddField(
 | 
				
			||||||
 | 
					#            model_name='explorer',
 | 
				
			||||||
 | 
					#            name='favorite_places',
 | 
				
			||||||
 | 
					#            field=models.ManyToManyField(blank=True, related_name='explorer_favorites', to='lostplaces.Place', verbose_name='Explorers favorite places'),
 | 
				
			||||||
 | 
					#        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='explorer',
 | 
				
			||||||
 | 
					            name='profile_image',
 | 
				
			||||||
 | 
					            field=easy_thumbnails.fields.ThumbnailerImageField(blank=True, help_text='Optional profile image for display in Explorer profile', null=True, upload_to=generate_profile_image_filename, verbose_name='Profile image'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='photoalbum',
 | 
				
			||||||
 | 
					            name='label',
 | 
				
			||||||
 | 
					            field=models.CharField(max_length=100, verbose_name='link text'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='photoalbum',
 | 
				
			||||||
 | 
					            name='submitted_by',
 | 
				
			||||||
 | 
					            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='photoalbums', to='lostplaces.explorer', verbose_name='Submitter'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='photoalbum',
 | 
				
			||||||
 | 
					            name='submitted_when',
 | 
				
			||||||
 | 
					            field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Submission date'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='photoalbum',
 | 
				
			||||||
 | 
					            name='url',
 | 
				
			||||||
 | 
					            field=models.URLField(verbose_name='URL'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='place',
 | 
				
			||||||
 | 
					            name='description',
 | 
				
			||||||
 | 
					            field=models.TextField(help_text="Description of the place: e.g. how to get there, where to be careful, the place's history...", verbose_name='Description'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='place',
 | 
				
			||||||
 | 
					            name='latitude',
 | 
				
			||||||
 | 
					            field=models.FloatField(help_text='Latitude in decimal format: e. g. 41.40338', validators=[django.core.validators.MinValueValidator(-90), django.core.validators.MaxValueValidator(90)], verbose_name='Latitude'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='place',
 | 
				
			||||||
 | 
					            name='location',
 | 
				
			||||||
 | 
					            field=models.CharField(max_length=50, verbose_name='Location'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='place',
 | 
				
			||||||
 | 
					            name='longitude',
 | 
				
			||||||
 | 
					            field=models.FloatField(help_text='Longitude in decimal format: e. g. 2.17403', validators=[django.core.validators.MinValueValidator(-180), django.core.validators.MaxValueValidator(180)], verbose_name='Longitude'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='place',
 | 
				
			||||||
 | 
					            name='name',
 | 
				
			||||||
 | 
					            field=models.CharField(max_length=50, verbose_name='Name'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='place',
 | 
				
			||||||
 | 
					            name='submitted_by',
 | 
				
			||||||
 | 
					            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='places', to='lostplaces.explorer', verbose_name='Submitter'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='place',
 | 
				
			||||||
 | 
					            name='submitted_when',
 | 
				
			||||||
 | 
					            field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Submission date'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='placeimage',
 | 
				
			||||||
 | 
					            name='description',
 | 
				
			||||||
 | 
					            field=models.TextField(blank=True, verbose_name='Description'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='placeimage',
 | 
				
			||||||
 | 
					            name='filename',
 | 
				
			||||||
 | 
					            field=easy_thumbnails.fields.ThumbnailerImageField(help_text='Optional: One or more images to upload', upload_to=generate_place_image_filename, verbose_name='Filename(s)'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='placeimage',
 | 
				
			||||||
 | 
					            name='submitted_by',
 | 
				
			||||||
 | 
					            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='placeimages', to='lostplaces.explorer', verbose_name='Submitter'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='placeimage',
 | 
				
			||||||
 | 
					            name='submitted_when',
 | 
				
			||||||
 | 
					            field=models.DateTimeField(auto_now_add=True, null=True, verbose_name='Submission date'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='voucher',
 | 
				
			||||||
 | 
					            name='created_when',
 | 
				
			||||||
 | 
					            field=models.DateTimeField(auto_now_add=True, verbose_name='Creation date'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AlterField(
 | 
				
			||||||
 | 
					            model_name='voucher',
 | 
				
			||||||
 | 
					            name='expires_when',
 | 
				
			||||||
 | 
					            field=models.DateTimeField(verbose_name='Expiration date'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					# Generated by Django 3.1.4 on 2020-12-25 18:14
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('lostplaces', '0004_auto_20201225_1702'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='explorer',
 | 
				
			||||||
 | 
					            name='visited_places',
 | 
				
			||||||
 | 
					            field=models.ManyToManyField(blank=True, related_name='explorer_visits', to='lostplaces.Place', verbose_name='Explorers visited places'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -6,19 +6,34 @@
 | 
				
			|||||||
database.
 | 
					database.
 | 
				
			||||||
'''
 | 
					'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
import uuid
 | 
					import uuid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
from django.db.models.signals import post_save
 | 
					from django.db.models.signals import post_save, pre_save
 | 
				
			||||||
from django.dispatch import receiver
 | 
					from django.dispatch import receiver
 | 
				
			||||||
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lostplaces.models.abstract_models import Expireable
 | 
					from lostplaces.models.abstract_models import Expireable
 | 
				
			||||||
 | 
					from lostplaces.models.place import Place
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from easy_thumbnails.fields import ThumbnailerImageField
 | 
				
			||||||
 | 
					from easy_thumbnails.files import get_thumbnailer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def generate_profile_image_filename(instance, filename):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Callback for generating filename for uploaded explorer profile images.
 | 
				
			||||||
 | 
					    Returns filename as: explorer_pk-username.jpg
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 'explorers/' + str(instance.user.pk) + '-' + str(instance.user.username) + '.' + filename.split('.')[-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Explorer(models.Model):
 | 
					class Explorer(models.Model):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Profile that is linked to the a User.
 | 
					    Profile that is linked to the Django user.
 | 
				
			||||||
    Every user has a profile.
 | 
					    Every user has a profile.
 | 
				
			||||||
 | 
					    Provides additional attributes for user profile.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    user = models.OneToOneField(
 | 
					    user = models.OneToOneField(
 | 
				
			||||||
@@ -26,6 +41,33 @@ class Explorer(models.Model):
 | 
				
			|||||||
        on_delete=models.CASCADE,
 | 
					        on_delete=models.CASCADE,
 | 
				
			||||||
        related_name='explorer'
 | 
					        related_name='explorer'
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					    bio = models.TextField(
 | 
				
			||||||
 | 
					        blank=True,
 | 
				
			||||||
 | 
					        null=True,
 | 
				
			||||||
 | 
					        verbose_name=_('Biography / Description'),
 | 
				
			||||||
 | 
					        help_text=_('Describe yourself, your preferences, etc. in a few sentences.')
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    profile_image = ThumbnailerImageField(
 | 
				
			||||||
 | 
					        blank=True,
 | 
				
			||||||
 | 
					        null=True,
 | 
				
			||||||
 | 
					        upload_to=generate_profile_image_filename, 
 | 
				
			||||||
 | 
					        resize_source=dict(size=(400, 400), 
 | 
				
			||||||
 | 
					        sharpen=True),
 | 
				
			||||||
 | 
					        verbose_name=_('Profile image'),
 | 
				
			||||||
 | 
					        help_text=_('Optional profile image for display in Explorer profile')
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    favorite_places = models.ManyToManyField(
 | 
				
			||||||
 | 
					        Place,
 | 
				
			||||||
 | 
					        related_name='explorer_favorites',
 | 
				
			||||||
 | 
					        verbose_name='Explorers favorite places',
 | 
				
			||||||
 | 
					        blank=True
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    visited_places = models.ManyToManyField(
 | 
				
			||||||
 | 
					        Place,
 | 
				
			||||||
 | 
					        related_name='explorer_visits',
 | 
				
			||||||
 | 
					        verbose_name='Explorers visited places',
 | 
				
			||||||
 | 
					        blank=True
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return self.user.username
 | 
					        return self.user.username
 | 
				
			||||||
@@ -39,13 +81,34 @@ def create_user_profile(sender, instance, created, **kwargs):
 | 
				
			|||||||
def save_user_profile(sender, instance, **kwargs):
 | 
					def save_user_profile(sender, instance, **kwargs):
 | 
				
			||||||
    instance.explorer.save()
 | 
					    instance.explorer.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@receiver(pre_save, sender=Explorer)
 | 
				
			||||||
 | 
					def auto_delete_file_on_change(sender, instance, **kwargs):
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Deletes old file from filesystem
 | 
				
			||||||
 | 
					    when corresponding `Explorer` object is updated
 | 
				
			||||||
 | 
					    with new file.
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    if not instance.pk:
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        old_file = Explorer.objects.get(pk=instance.pk).profile_image
 | 
				
			||||||
 | 
					    except Explorer.DoesNotExist:
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					    print("Deleting:", old_file)
 | 
				
			||||||
 | 
					    new_file = instance.profile_image
 | 
				
			||||||
 | 
					    if not old_file == new_file:
 | 
				
			||||||
 | 
					        old_file.delete(save=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Voucher(Expireable):
 | 
					class Voucher(Expireable):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Vouchers are authorization to    created_when = models.DateTimeField(auto_now_add=True)
 | 
					    Vouchers are authorization tokens to allow the registration of new users.
 | 
				
			||||||
    expires_when = models.DateTimeField()kens to allow the registration of new users.
 | 
					 | 
				
			||||||
    A voucher has a code, a creation and a deletion date, which are all 
 | 
					    A voucher has a code, a creation and a deletion date, which are all 
 | 
				
			||||||
    positional. Creation date is being set automatically during voucher 
 | 
					    positional. Creation date is being set automatically during voucher 
 | 
				
			||||||
    creation. 
 | 
					    creation. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    created_when = models.DateTimeField(auto_now_add=True)
 | 
				
			||||||
 | 
					    expires_when = models.DateTimeField()
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    code = models.CharField(unique=True, max_length=30)
 | 
					    code = models.CharField(unique=True, max_length=30)
 | 
				
			||||||
@@ -56,4 +119,3 @@ class Voucher(Expireable):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return "Voucher " + str(self.code)
 | 
					        return "Voucher " + str(self.code)
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,10 +49,10 @@ class Place(Submittable, Taggable, Mapable):
 | 
				
			|||||||
        return self.name
 | 
					        return self.name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def generate_image_upload_path(instance, filename):
 | 
					def generate_place_image_filename(instance, filename):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Callback for generating path for uploaded images.
 | 
					    Callback for generating filename for uploaded place images.
 | 
				
			||||||
    Returns filename as: place_pk-placename{-rnd_string}.jpg
 | 
					    Returns filename as: place_pk-placename{-number}.jpg
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 'places/' + str(instance.place.pk) + '-' + str(instance.place.name) + '.' + filename.split('.')[-1]
 | 
					    return 'places/' + str(instance.place.pk) + '-' + str(instance.place.name) + '.' + filename.split('.')[-1]
 | 
				
			||||||
@@ -72,7 +72,7 @@ class PlaceAsset(Submittable):
 | 
				
			|||||||
        null=True
 | 
					        null=True
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlaceImage (PlaceAsset):
 | 
					class PlaceImage(PlaceAsset):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    PlaceImage defines an image file object that points to a file in uploads/.
 | 
					    PlaceImage defines an image file object that points to a file in uploads/.
 | 
				
			||||||
    Intermediate image sizes are generated as defined in THUMBNAIL_ALIASES.
 | 
					    Intermediate image sizes are generated as defined in THUMBNAIL_ALIASES.
 | 
				
			||||||
@@ -84,7 +84,7 @@ class PlaceImage (PlaceAsset):
 | 
				
			|||||||
        verbose_name=_('Description'),
 | 
					        verbose_name=_('Description'),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    filename = ThumbnailerImageField(
 | 
					    filename = ThumbnailerImageField(
 | 
				
			||||||
        upload_to=generate_image_upload_path, 
 | 
					        upload_to=generate_place_image_filename, 
 | 
				
			||||||
        resize_source=dict(size=(2560, 2560), 
 | 
					        resize_source=dict(size=(2560, 2560), 
 | 
				
			||||||
        sharpen=True),
 | 
					        sharpen=True),
 | 
				
			||||||
        verbose_name=_('Filename(s)'),
 | 
					        verbose_name=_('Filename(s)'),
 | 
				
			||||||
@@ -104,7 +104,6 @@ class PlaceImage (PlaceAsset):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return 'Image ' + str(self.pk)
 | 
					        return 'Image ' + str(self.pk)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
# These two auto-delete files from filesystem when they are unneeded:
 | 
					# These two auto-delete files from filesystem when they are unneeded:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@receiver(post_delete, sender=PlaceImage)
 | 
					@receiver(post_delete, sender=PlaceImage)
 | 
				
			||||||
@@ -118,7 +117,6 @@ def auto_delete_file_on_delete(sender, instance, **kwargs):
 | 
				
			|||||||
        thumbmanager = get_thumbnailer(instance.filename)
 | 
					        thumbmanager = get_thumbnailer(instance.filename)
 | 
				
			||||||
        thumbmanager.delete(save=False)
 | 
					        thumbmanager.delete(save=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
@receiver(pre_save, sender=PlaceImage)
 | 
					@receiver(pre_save, sender=PlaceImage)
 | 
				
			||||||
def auto_delete_file_on_change(sender, instance, **kwargs):
 | 
					def auto_delete_file_on_change(sender, instance, **kwargs):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
@@ -137,5 +135,4 @@ def auto_delete_file_on_change(sender, instance, **kwargs):
 | 
				
			|||||||
    # No need to delete thumbnails, as they will be overwritten on regeneration.
 | 
					    # No need to delete thumbnails, as they will be overwritten on regeneration.
 | 
				
			||||||
    new_file = instance.filename
 | 
					    new_file = instance.filename
 | 
				
			||||||
    if not old_file == new_file:
 | 
					    if not old_file == new_file:
 | 
				
			||||||
        if os.path.isfile(old_file.path):
 | 
					        old_file.delete(save=False)
 | 
				
			||||||
            os.remove(old_file.path)
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB  | 
							
								
								
									
										163
									
								
								django_lostplaces/lostplaces/static/icons/favorite_filled.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								django_lostplaces/lostplaces/static/icons/favorite_filled.svg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 After Width: | Height: | Size: 108 KiB  | 
							
								
								
									
										50
									
								
								django_lostplaces/lostplaces/static/icons/pin.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								django_lostplaces/lostplaces/static/icons/pin.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="iso-8859-1"?>
 | 
				
			||||||
 | 
					<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
 | 
				
			||||||
 | 
					<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 | 
				
			||||||
 | 
						 viewBox="0 0 368.16 368.16" style="enable-background:new 0 0 368.16 368.16;" xml:space="preserve">
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
						<g>
 | 
				
			||||||
 | 
							<g>
 | 
				
			||||||
 | 
								<path d="M184.08,0c-74.992,0-136,61.008-136,136c0,24.688,11.072,51.24,11.536,52.36c3.576,8.488,10.632,21.672,15.72,29.4
 | 
				
			||||||
 | 
									l93.248,141.288c3.816,5.792,9.464,9.112,15.496,9.112s11.68-3.32,15.496-9.104l93.256-141.296
 | 
				
			||||||
 | 
									c5.096-7.728,12.144-20.912,15.72-29.4c0.464-1.112,11.528-27.664,11.528-52.36C320.08,61.008,259.072,0,184.08,0z
 | 
				
			||||||
 | 
									 M293.8,182.152c-3.192,7.608-9.76,19.872-14.328,26.8l-93.256,141.296c-1.84,2.792-2.424,2.792-4.264,0L88.696,208.952
 | 
				
			||||||
 | 
									c-4.568-6.928-11.136-19.2-14.328-26.808C74.232,181.816,64.08,157.376,64.08,136c0-66.168,53.832-120,120-120
 | 
				
			||||||
 | 
									c66.168,0,120,53.832,120,120C304.08,157.408,293.904,181.912,293.8,182.152z"/>
 | 
				
			||||||
 | 
								<path d="M184.08,64.008c-39.704,0-72,32.304-72,72c0,39.696,32.296,72,72,72c39.704,0,72-32.304,72-72
 | 
				
			||||||
 | 
									C256.08,96.312,223.784,64.008,184.08,64.008z M184.08,192.008c-30.872,0-56-25.12-56-56s25.128-56,56-56s56,25.12,56,56
 | 
				
			||||||
 | 
									S214.952,192.008,184.08,192.008z"/>
 | 
				
			||||||
 | 
							</g>
 | 
				
			||||||
 | 
						</g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 1.5 KiB  | 
							
								
								
									
										105
									
								
								django_lostplaces/lostplaces/static/icons/pin_filled.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								django_lostplaces/lostplaces/static/icons/pin_filled.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
				
			||||||
 | 
					<svg
 | 
				
			||||||
 | 
					   xmlns:dc="http://purl.org/dc/elements/1.1/"
 | 
				
			||||||
 | 
					   xmlns:cc="http://creativecommons.org/ns#"
 | 
				
			||||||
 | 
					   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 | 
				
			||||||
 | 
					   xmlns:svg="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns="http://www.w3.org/2000/svg"
 | 
				
			||||||
 | 
					   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
				
			||||||
 | 
					   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
				
			||||||
 | 
					   version="1.1"
 | 
				
			||||||
 | 
					   id="Capa_1"
 | 
				
			||||||
 | 
					   x="0px"
 | 
				
			||||||
 | 
					   y="0px"
 | 
				
			||||||
 | 
					   viewBox="0 0 368.16 368.16"
 | 
				
			||||||
 | 
					   style="enable-background:new 0 0 368.16 368.16;"
 | 
				
			||||||
 | 
					   xml:space="preserve"
 | 
				
			||||||
 | 
					   sodipodi:docname="pin_filled.svg"
 | 
				
			||||||
 | 
					   inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"><metadata
 | 
				
			||||||
 | 
					   id="metadata47"><rdf:RDF><cc:Work
 | 
				
			||||||
 | 
					       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
 | 
				
			||||||
 | 
					         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
 | 
				
			||||||
 | 
					   id="defs45" /><sodipodi:namedview
 | 
				
			||||||
 | 
					   pagecolor="#ffffff"
 | 
				
			||||||
 | 
					   bordercolor="#666666"
 | 
				
			||||||
 | 
					   borderopacity="1"
 | 
				
			||||||
 | 
					   objecttolerance="10"
 | 
				
			||||||
 | 
					   gridtolerance="10"
 | 
				
			||||||
 | 
					   guidetolerance="10"
 | 
				
			||||||
 | 
					   inkscape:pageopacity="0"
 | 
				
			||||||
 | 
					   inkscape:pageshadow="2"
 | 
				
			||||||
 | 
					   inkscape:window-width="1366"
 | 
				
			||||||
 | 
					   inkscape:window-height="712"
 | 
				
			||||||
 | 
					   id="namedview43"
 | 
				
			||||||
 | 
					   showgrid="false"
 | 
				
			||||||
 | 
					   inkscape:zoom="1.4803346"
 | 
				
			||||||
 | 
					   inkscape:cx="184.08"
 | 
				
			||||||
 | 
					   inkscape:cy="181.37791"
 | 
				
			||||||
 | 
					   inkscape:window-x="0"
 | 
				
			||||||
 | 
					   inkscape:window-y="28"
 | 
				
			||||||
 | 
					   inkscape:window-maximized="1"
 | 
				
			||||||
 | 
					   inkscape:current-layer="Capa_1" />
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g10">
 | 
				
			||||||
 | 
						<g
 | 
				
			||||||
 | 
					   id="g8">
 | 
				
			||||||
 | 
							<g
 | 
				
			||||||
 | 
					   id="g6">
 | 
				
			||||||
 | 
								<path
 | 
				
			||||||
 | 
					   d="M184.08,0c-74.992,0-136,61.008-136,136c0,24.688,11.072,51.24,11.536,52.36c3.576,8.488,10.632,21.672,15.72,29.4     l93.248,141.288c3.816,5.792,9.464,9.112,15.496,9.112s11.68-3.32,15.496-9.104l93.256-141.296     c5.096-7.728,12.144-20.912,15.72-29.4c0.464-1.112,11.528-27.664,11.528-52.36C320.08,61.008,259.072,0,184.08,0z      M293.8,182.152c-3.192,7.608-9.76,19.872-14.328,26.8l-93.256,141.296c-1.84,2.792-2.424,2.792-4.264,0L88.696,208.952     c-4.568-6.928-11.136-19.2-14.328-26.808C74.232,181.816,64.08,157.376,64.08,136c0-66.168,53.832-120,120-120     c66.168,0,120,53.832,120,120C304.08,157.408,293.904,181.912,293.8,182.152z"
 | 
				
			||||||
 | 
					   id="path2" />
 | 
				
			||||||
 | 
								<path
 | 
				
			||||||
 | 
					   d="M184.08,64.008c-39.704,0-72,32.304-72,72c0,39.696,32.296,72,72,72c39.704,0,72-32.304,72-72     C256.08,96.312,223.784,64.008,184.08,64.008z M184.08,192.008c-30.872,0-56-25.12-56-56s25.128-56,56-56s56,25.12,56,56     S214.952,192.008,184.08,192.008z"
 | 
				
			||||||
 | 
					   id="path4" />
 | 
				
			||||||
 | 
							</g>
 | 
				
			||||||
 | 
						</g>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g12">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g14">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g16">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g18">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g20">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g22">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g24">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g26">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g28">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g30">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g32">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g34">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g36">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g38">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g
 | 
				
			||||||
 | 
					   id="g40">
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<path
 | 
				
			||||||
 | 
					   style="fill:#d40000;stroke-width:0.675523"
 | 
				
			||||||
 | 
					   d="M 183.2356,15.407728 C 148.115,15.680007 113.56046,32.165752 91.281357,59.335191 67.968201,87.080284 57.903075,125.97636 67.012946,161.30636 c 5.002813,21.56622 16.217838,40.96402 28.671518,59.02158 29.047926,44.21623 57.936976,88.55418 87.673836,132.30559 2.75528,0.71398 3.44582,-3.87416 5.23173,-5.36255 32.63958,-48.91094 65.16056,-97.91511 96.89098,-147.42174 14.94799,-26.09698 23.38967,-57.3347 16.79888,-87.25041 C 297.41258,88.732147 285.50707,66.159988 267.48079,49.622901 254.86863,36.299556 238.35251,27.47624 221.24564,21.334387 209.00763,17.320382 196.11719,15.285641 183.2356,15.407728 Z m 2.03448,49.555941 c 27.46439,-0.566602 54.10132,17.912787 64.54543,43.490751 4.10895,9.11958 5.7106,19.04018 5.10583,29.01713 0.83931,19.32103 -8.79389,38.15287 -22.74612,51.10133 -14.02478,12.97799 -33.27348,19.77398 -52.19585,18.33769 -29.18994,-0.56334 -56.21632,-22.71956 -64.31454,-50.57715 -3.46488,-10.42859 -2.56691,-21.58508 -1.94784,-32.37905 3.96475,-21.34187 17.606,-41.232363 37.2523,-51.078299 10.71386,-5.480174 22.38724,-8.587404 34.30079,-7.912402 z"
 | 
				
			||||||
 | 
					   id="path91" /></svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 3.8 KiB  | 
@@ -923,7 +923,8 @@ body {
 | 
				
			|||||||
      justify-content: space-between;
 | 
					      justify-content: space-between;
 | 
				
			||||||
      align-items: flex-start;
 | 
					      align-items: flex-start;
 | 
				
			||||||
      gap: unset; }
 | 
					      gap: unset; }
 | 
				
			||||||
      .LP-PlaceTeaser--extended .LP-PlaceTeaser__Meta .LP-Headline, .LP-PlaceTeaser--extended .LP-PlaceTeaser__Meta .LP-Paragraph {
 | 
					      .LP-PlaceTeaser--extended .LP-PlaceTeaser__Meta .LP-Headline,
 | 
				
			||||||
 | 
					      .LP-PlaceTeaser--extended .LP-PlaceTeaser__Meta .LP-Paragraph {
 | 
				
			||||||
        font-size: unset; }
 | 
					        font-size: unset; }
 | 
				
			||||||
      .LP-PlaceTeaser--extended .LP-PlaceTeaser__Meta .LP-PlaceTeaser__Info .LP-Headline {
 | 
					      .LP-PlaceTeaser--extended .LP-PlaceTeaser__Meta .LP-PlaceTeaser__Info .LP-Headline {
 | 
				
			||||||
        font-size: 28px; }
 | 
					        font-size: 28px; }
 | 
				
			||||||
@@ -941,7 +942,12 @@ body {
 | 
				
			|||||||
      overflow: hidden;
 | 
					      overflow: hidden;
 | 
				
			||||||
      order: unset; }
 | 
					      order: unset; }
 | 
				
			||||||
      .LP-PlaceTeaser--extended .LP-PlaceTeaser__Description .LP-Paragraph {
 | 
					      .LP-PlaceTeaser--extended .LP-PlaceTeaser__Description .LP-Paragraph {
 | 
				
			||||||
        font-size: unset; }
 | 
					        font-size: unset;
 | 
				
			||||||
 | 
					        display: -webkit-box;
 | 
				
			||||||
 | 
					        -webkit-box-orient: vertical;
 | 
				
			||||||
 | 
					        -webkit-line-clamp: 2;
 | 
				
			||||||
 | 
					        overflow: hidden;
 | 
				
			||||||
 | 
					        text-overflow: ellipsis; }
 | 
				
			||||||
    .LP-PlaceTeaser--extended .LP-PlaceTeaser__Image {
 | 
					    .LP-PlaceTeaser--extended .LP-PlaceTeaser__Image {
 | 
				
			||||||
      height: 165px;
 | 
					      height: 165px;
 | 
				
			||||||
      width: 280px;
 | 
					      width: 280px;
 | 
				
			||||||
@@ -1695,6 +1701,11 @@ body {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.LP-Map {
 | 
					.LP-Map {
 | 
				
			||||||
  margin-bottom: 25px; }
 | 
					  margin-bottom: 25px; }
 | 
				
			||||||
 | 
					  .LP-Map--wide {
 | 
				
			||||||
 | 
					    height: 300px; }
 | 
				
			||||||
 | 
					  .LP-Map--full {
 | 
				
			||||||
 | 
					    height: 100%;
 | 
				
			||||||
 | 
					    width: 100%; }
 | 
				
			||||||
  .LP-Map .ol-attribution {
 | 
					  .LP-Map .ol-attribution {
 | 
				
			||||||
    font-family: "Montserrat", Helvetica, sans-serif;
 | 
					    font-family: "Montserrat", Helvetica, sans-serif;
 | 
				
			||||||
    color: #565656; }
 | 
					    color: #565656; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,13 +7,46 @@
 | 
				
			|||||||
{% block maincontent %}
 | 
					{% block maincontent %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="LP-UserProfile">
 | 
					<div class="LP-UserProfile">
 | 
				
			||||||
 | 
						<div class="LP-UserProfile__Bio">
 | 
				
			||||||
 | 
					        <h2 class="LP-Headline">Bio</h2>
 | 
				
			||||||
 | 
					        <p class="LP-Paragraph">{{explorer.bio}}</p>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
    <div class="LP-UserProfile__Info">
 | 
					    <div class="LP-UserProfile__Info">
 | 
				
			||||||
        <div class="LP-UserInfo">
 | 
					        <div class="LP-UserInfo">
 | 
				
			||||||
            <div class="LP-UserInfo__UserName">
 | 
					            <div class="LP-UserInfo__UserName">
 | 
				
			||||||
                <h1 class="LP-Headline">{{explorer.user.username}}</h1>
 | 
					                <h1 class="LP-Headline">{{explorer.user.username}}</h1>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <div class="LP-UserInfo__Meta">
 | 
					            <div class="LP-UserInfo__Meta">
 | 
				
			||||||
                <table>
 | 
					                <table>
 | 
				
			||||||
 | 
										<tr>
 | 
				
			||||||
 | 
											{% if explorer.profile_image %}
 | 
				
			||||||
 | 
											<figure class="LP-UserInfo__Image">
 | 
				
			||||||
 | 
												<img src="{{ explorer.profile_image.url }}" class="LP-Image" />
 | 
				
			||||||
 | 
											</figure>
 | 
				
			||||||
 | 
											{% endif %}
 | 
				
			||||||
 | 
					                    <tr>
 | 
				
			||||||
 | 
											{% if explorer.user.first_name %}
 | 
				
			||||||
 | 
					                        <td class="LP-UserInfo__Key">
 | 
				
			||||||
 | 
					                            <span class="LP-Paragraph">{% trans 'Name' %}</span>
 | 
				
			||||||
 | 
					                        </td>
 | 
				
			||||||
 | 
					                        <td class="LP-UserInfo__Value">
 | 
				
			||||||
 | 
					                            <span class="LP-Paragraph">{{explorer.user.first_name}} {{explorer.user.last_name}}</span>
 | 
				
			||||||
 | 
					                        </td>
 | 
				
			||||||
 | 
											{% endif %}
 | 
				
			||||||
 | 
					                    </tr>
 | 
				
			||||||
 | 
					                    <tr>
 | 
				
			||||||
 | 
					                        {% if explorer.user.email %}
 | 
				
			||||||
 | 
											<td class="LP-UserInfo__Key">
 | 
				
			||||||
 | 
					                            <span class="LP-Paragraph">{% trans 'E-mail' %}</span>
 | 
				
			||||||
 | 
					                        </td>
 | 
				
			||||||
 | 
					                        <td class="LP-UserInfo__Value">
 | 
				
			||||||
 | 
												<span class="LP-Paragraph">
 | 
				
			||||||
 | 
					                            	<a href="{{explorer.user.email}}" class="LP-Link">{{explorer.user.email}}</a>
 | 
				
			||||||
 | 
												</span>
 | 
				
			||||||
 | 
					                        </td>
 | 
				
			||||||
 | 
											{% endif %}
 | 
				
			||||||
 | 
					                    </tr>
 | 
				
			||||||
                    <tr>
 | 
					                    <tr>
 | 
				
			||||||
                        <td class="LP-UserInfo__Key">
 | 
					                        <td class="LP-UserInfo__Key">
 | 
				
			||||||
                            <span class="LP-Paragraph">{% trans 'Joined' %}</span>
 | 
					                            <span class="LP-Paragraph">{% trans 'Joined' %}</span>
 | 
				
			||||||
@@ -32,12 +65,17 @@
 | 
				
			|||||||
                    </tr>
 | 
					                    </tr>
 | 
				
			||||||
                    <tr>
 | 
					                    <tr>
 | 
				
			||||||
                        <td class="LP-UserInfo__Key">
 | 
					                        <td class="LP-UserInfo__Key">
 | 
				
			||||||
                            <span class="LP-Paragraph">{% trans 'Place Assets'%}</span>
 | 
					                            <span class="LP-Paragraph">{% trans 'Place assets'%}</span>
 | 
				
			||||||
                        </td>
 | 
					                        </td>
 | 
				
			||||||
                        <td class="LP-UserInfo__Value">
 | 
					                        <td class="LP-UserInfo__Value">
 | 
				
			||||||
                            <span class="LP-Paragraph">{{asset_count}}</span>
 | 
					                            <span class="LP-Paragraph">{{asset_count}}</span>
 | 
				
			||||||
                        </td>
 | 
					                        </td>
 | 
				
			||||||
                    </tr>
 | 
					                    </tr>
 | 
				
			||||||
 | 
					                    <tr>
 | 
				
			||||||
 | 
					                        <td>
 | 
				
			||||||
 | 
					                            <a href="/explorer/update/"><button class="LP-Button LP-Button">{% trans 'Edit Profile' %}</button></a>
 | 
				
			||||||
 | 
					                        </td>
 | 
				
			||||||
 | 
					                    </tr>
 | 
				
			||||||
                </table>
 | 
					                </table>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
@@ -45,65 +83,91 @@
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<section class="LP-Section">
 | 
					<section class="LP-Section">
 | 
				
			||||||
	<div class="LP-PlaceList">
 | 
					    <div class="LP-PlaceList">
 | 
				
			||||||
		<h1 class="LP-Headline">{% trans 'Places submitted by' %} {{explorer.user.username}}</h1>
 | 
					        <h1 class="LP-Headline">{% trans 'Favorite places' %}</h1>
 | 
				
			||||||
		<ul class="LP-PlaceList__List">
 | 
					        <ul class="LP-PlaceList__List">
 | 
				
			||||||
			{% for place in place_list %}
 | 
					            {% for place in explorer.favorite_places.all %}
 | 
				
			||||||
			<li class="LP-PlaceList__Item">
 | 
					            <li class="LP-PlaceList__Item">
 | 
				
			||||||
				<a href="{% url 'place_detail' pk=place.pk %}" class="LP-Link">
 | 
					                {% include 'partials/place_teaser.html' with place=place extended=True %}
 | 
				
			||||||
					{% include 'partials/place_teaser.html' with place=place extended=True %}
 | 
					            </li>
 | 
				
			||||||
				</a>
 | 
					            {% endfor %}
 | 
				
			||||||
			</li>
 | 
					        </ul>
 | 
				
			||||||
			{% endfor %}
 | 
					        {% include 'partials/nav/pagination.html' %}
 | 
				
			||||||
		</ul>
 | 
					    </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
		{% include 'partials/nav/pagination.html' %}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	</div>
 | 
					 | 
				
			||||||
</section>
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<section class="LP-Section">
 | 
					<section class="LP-Section">
 | 
				
			||||||
	<h1 class="LP-Headline">{% trans 'Images submitted by' %} {{explorer.user.username}}</h1>
 | 
					    <div class="LP-PlaceList">
 | 
				
			||||||
	<div class="LP-ImageGrid">
 | 
					        <h1 class="LP-Headline">{% trans 'Visited places' %}</h1>
 | 
				
			||||||
		<ul class="LP-ImageGrid__Container">
 | 
					        <ul class="LP-PlaceList__List">
 | 
				
			||||||
			{% for place_image in assets.placeimages.all %}
 | 
					            {% for place in explorer.visited_places.all %}
 | 
				
			||||||
			<li class="LP-ImageGrid__Item">
 | 
					            <li class="LP-PlaceList__Item">
 | 
				
			||||||
				<a href="{{ place_image.filename.large.url }}" class="LP-Link">
 | 
					                {% include 'partials/place_teaser.html' with place=place extended=True %}
 | 
				
			||||||
					<img class="LP-Image" src="{{ place_image.filename.thumbnail.url }}">
 | 
					            </li>
 | 
				
			||||||
				</a>
 | 
					            {% endfor %}
 | 
				
			||||||
				{% if user.explorer == place_image.submitted_by%}
 | 
					        </ul>
 | 
				
			||||||
				<span class="LP-ImageGrid__DeleteItem" title="Bild löschen">
 | 
					        {% include 'partials/nav/pagination.html' %}
 | 
				
			||||||
					<a href="{% url 'place_image_delete' pk=place_image.id %}" class="LP-Link">
 | 
					    </div>
 | 
				
			||||||
						<img class="LP-Icon" src="{% static 'icons/cancel.svg' %}" />
 | 
					</section>
 | 
				
			||||||
					</a>
 | 
					
 | 
				
			||||||
				</span>
 | 
					<section class="LP-Section">
 | 
				
			||||||
				{% endif %}
 | 
					    <div class="LP-PlaceList">
 | 
				
			||||||
			</li>
 | 
					        <h1 class="LP-Headline">{% trans 'Places submitted by' %} {{explorer.user.username}}</h1>
 | 
				
			||||||
			{% endfor %}
 | 
					        <ul class="LP-PlaceList__List">
 | 
				
			||||||
		</ul>
 | 
					            {% for place in place_list %}
 | 
				
			||||||
	</div>
 | 
					            <li class="LP-PlaceList__Item">
 | 
				
			||||||
 | 
					                {% include 'partials/place_teaser.html' with place=place extended=True %}
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					            {% endfor %}
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {% include 'partials/nav/pagination.html' %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<section class="LP-Section">
 | 
				
			||||||
 | 
					    <h1 class="LP-Headline">{% trans 'Images submitted by' %} {{explorer.user.username}}</h1>
 | 
				
			||||||
 | 
					    <div class="LP-ImageGrid">
 | 
				
			||||||
 | 
					        <ul class="LP-ImageGrid__Container">
 | 
				
			||||||
 | 
					            {% for place_image in assets.placeimages.all %}
 | 
				
			||||||
 | 
					            <li class="LP-ImageGrid__Item">
 | 
				
			||||||
 | 
					                <a href="{{ place_image.filename.large.url }}" class="LP-Link">
 | 
				
			||||||
 | 
					                    <img class="LP-Image" src="{{ place_image.filename.thumbnail.url }}">
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					                {% if user.explorer == place_image.submitted_by%}
 | 
				
			||||||
 | 
					                <span class="LP-ImageGrid__DeleteItem" title="Bild löschen">
 | 
				
			||||||
 | 
					                    <a href="{% url 'place_image_delete' pk=place_image.id %}" class="LP-Link">
 | 
				
			||||||
 | 
					                        <img class="LP-Icon" src="{% static 'icons/cancel.svg' %}" />
 | 
				
			||||||
 | 
					                    </a>
 | 
				
			||||||
 | 
					                </span>
 | 
				
			||||||
 | 
					                {% endif %}
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					            {% endfor %}
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
</section>
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<section class=" LP-Section">
 | 
					<section class=" LP-Section">
 | 
				
			||||||
	<h1 class="LP-Headline">{% trans 'Photo albums submitted by' %} {{explorer.user.username}}</h1>
 | 
					    <h1 class="LP-Headline">{% trans 'Photo albums submitted by' %} {{explorer.user.username}}</h1>
 | 
				
			||||||
	<div class="LP-LinkList">
 | 
					    <div class="LP-LinkList">
 | 
				
			||||||
		<ul class="LP-LinkList__Container">
 | 
					        <ul class="LP-LinkList__Container">
 | 
				
			||||||
			{% for photo_album in assets.photoalbums.all %}
 | 
					            {% for photo_album in assets.photoalbums.all %}
 | 
				
			||||||
			<li class="LP-LinkList__Item">
 | 
					            <li class="LP-LinkList__Item">
 | 
				
			||||||
				<a target="_blank" href="{{photo_album.url}}" class="LP-Link">
 | 
					                <a target="_blank" href="{{photo_album.url}}" class="LP-Link">
 | 
				
			||||||
					<span class="LP-Text">{{photo_album.label}}</span>
 | 
					                    <span class="LP-Text">{{photo_album.label}}</span>
 | 
				
			||||||
				</a>
 | 
					                </a>
 | 
				
			||||||
				{% if user.explorer == photo_album.submitted_by%}
 | 
					                {% if user.explorer == photo_album.submitted_by%}
 | 
				
			||||||
				<a href="{% url 'photo_album_delete' pk=photo_album.pk%}" class="LP-Link LP-LinkList__ItemHover" title="Delete Photo Album">
 | 
					                <a href="{% url 'photo_album_delete' pk=photo_album.pk%}" class="LP-Link LP-LinkList__ItemHover" title="Delete Photo Album">
 | 
				
			||||||
					<div class="RV-Iconized__Container RV-Iconized__Container--small">
 | 
					                    <div class="RV-Iconized__Container RV-Iconized__Container--small">
 | 
				
			||||||
						{% icon 'trash' className="RV-Iconized__Icon" %}
 | 
					                        {% icon 'trash' className="RV-Iconized__Icon" %}
 | 
				
			||||||
					</div>
 | 
					                    </div>
 | 
				
			||||||
				</a>
 | 
					                </a>
 | 
				
			||||||
				{% endif %}
 | 
					                {% endif %}
 | 
				
			||||||
			</li>
 | 
					            </li>
 | 
				
			||||||
			{% endfor %}
 | 
					            {% endfor %}
 | 
				
			||||||
		</ul>
 | 
					        </ul>
 | 
				
			||||||
	</div>
 | 
					    </div>
 | 
				
			||||||
</section>
 | 
					</section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% endblock maincontent %}
 | 
					{% endblock maincontent %}
 | 
				
			||||||
@@ -0,0 +1,55 @@
 | 
				
			|||||||
 | 
					{% extends 'global.html'%}
 | 
				
			||||||
 | 
					{% load i18n %}
 | 
				
			||||||
 | 
					{% load thumbnail %}
 | 
				
			||||||
 | 
					{% load widget_tweaks %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# {% block title %}{% trans 'Edit Explorer profile' %}{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block maincontent %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<form class="LP-Form" method="POST" enctype="multipart/form-data">
 | 
				
			||||||
 | 
					    <fieldset class="LP-Form__Fieldset">
 | 
				
			||||||
 | 
					        <legend class="LP-Form__Legend">{% trans 'Edit Explorer profile' %}</legend>
 | 
				
			||||||
 | 
					        {% csrf_token %}
 | 
				
			||||||
 | 
					        <div class="LP-Form__Composition LP-Form__Composition--breakable">
 | 
				
			||||||
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 | 
					                {% include 'partials/form/inputField.html' with field=explorer_user_change_form.username %}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 | 
					                {% include 'partials/form/inputField.html' with field=explorer_user_change_form.email %}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="LP-Form__Composition LP-Form__Composition--breakable">
 | 
				
			||||||
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 | 
					                {% include 'partials/form/inputField.html' with field=explorer_user_change_form.first_name %}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 | 
					                {% include 'partials/form/inputField.html' with field=explorer_user_change_form.last_name %}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="LP-Form__Composition">
 | 
				
			||||||
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 | 
					                {% include 'partials/form/inputField.html' with field=explorer_change_form.bio %}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <div class="LP-Form__Composition">
 | 
				
			||||||
 | 
					            {% if explorer_image %}
 | 
				
			||||||
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 | 
					                <img src="{% thumbnail explorer_image 200x200 %}"/>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            {% endif %}
 | 
				
			||||||
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 | 
					                {% include 'partials/form/inputField.html' with field=explorer_change_form.profile_image %}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        {% trans 'Update' as action %}
 | 
				
			||||||
 | 
					        <div class="LP-Form__Composition LP-Form__Composition--buttons">
 | 
				
			||||||
 | 
					            {% include 'partials/form/submit.html' with referrer=request.META.HTTP_REFERER action=action %}
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </fieldset>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% endblock maincontent %}
 | 
				
			||||||
@@ -30,7 +30,7 @@
 | 
				
			|||||||
                    {% if user.is_authenticated %}
 | 
					                    {% if user.is_authenticated %}
 | 
				
			||||||
                    Hi {{ user.username }}!
 | 
					                    Hi {{ user.username }}!
 | 
				
			||||||
                    <a class="LP-Link" href="{% url 'logout' %}"><span class="LP-Link__Text">{% trans 'Logout' %}</span></a> |
 | 
					                    <a class="LP-Link" href="{% url 'logout' %}"><span class="LP-Link__Text">{% trans 'Logout' %}</span></a> |
 | 
				
			||||||
					<a class="LP-Link" href="{% url 'explorer_profile' explorer_id=user.pk%}"><span class="LP-Link__Text">{% trans 'Profile' %}</span></a>
 | 
					                    <a class="LP-Link" href="{% url 'explorer_profile' explorer_id=user.pk%}"><span class="LP-Link__Text">{% trans 'Profile' %}</span></a>
 | 
				
			||||||
                    {% if user.is_superuser %}
 | 
					                    {% if user.is_superuser %}
 | 
				
			||||||
                    | <a class="LP-Link" href="{% url 'admin:index' %}" target="_blank"><span class="LP-Link__Text">{% trans 'Admin' %}</span></a>
 | 
					                    | <a class="LP-Link" href="{% url 'admin:index' %}" target="_blank"><span class="LP-Link__Text">{% trans 'Admin' %}</span></a>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
@@ -50,7 +50,7 @@
 | 
				
			|||||||
                <ul class="LP-Menu__List">
 | 
					                <ul class="LP-Menu__List">
 | 
				
			||||||
                    <li class="LP-Menu__Item"><a href="{% url 'lostplaces_home' %}" class="LP-Link"><span class="LP-Link__Text">{% trans 'Home' %}</span></a></li>
 | 
					                    <li class="LP-Menu__Item"><a href="{% url 'lostplaces_home' %}" class="LP-Link"><span class="LP-Link__Text">{% trans 'Home' %}</span></a></li>
 | 
				
			||||||
                    <li class="LP-Menu__Item"><a href="{% url 'flatpage' slug='codex' %}" class="LP-Link"><span class="LP-Link__Text">{% trans 'UrBex Codex' %}</span></a></li>
 | 
					                    <li class="LP-Menu__Item"><a href="{% url 'flatpage' slug='codex' %}" class="LP-Link"><span class="LP-Link__Text">{% trans 'UrBex Codex' %}</span></a></li>
 | 
				
			||||||
 | 
					                    <li class="LP-Menu__Item"><a href="{% url 'osm' %}" class="LP-Link"><span class="LP-Link__Text">{% trans 'Map' %}</span></a></li>
 | 
				
			||||||
                    {% block additional_menu_items %}
 | 
					                    {% block additional_menu_items %}
 | 
				
			||||||
                    {% endblock additional_menu_items %}
 | 
					                    {% endblock additional_menu_items %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,15 +15,13 @@
 | 
				
			|||||||
<article class="LP-TextSection">
 | 
					<article class="LP-TextSection">
 | 
				
			||||||
</article>
 | 
					</article>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% include 'partials/osm_map.html' with config=mapping_config %}
 | 
					{% include 'partials/osm_map.html' with config=mapping_config modifier='wide' %}
 | 
				
			||||||
<div class="LP-PlaceGrid">
 | 
					<div class="LP-PlaceGrid">
 | 
				
			||||||
    <h1 class="LP-Headline LP-Headline">{% trans 'Explore the latest places' %}</h1>
 | 
					    <h1 class="LP-Headline LP-Headline">{% trans 'Explore the latest places' %}</h1>
 | 
				
			||||||
    <ul class="LP-PlaceGrid__Grid">
 | 
					    <ul class="LP-PlaceGrid__Grid">
 | 
				
			||||||
        {% for place in place_list %}
 | 
					        {% for place in place_list %}
 | 
				
			||||||
        <li class="LP-PlaceGrid__Item">
 | 
					        <li class="LP-PlaceGrid__Item">
 | 
				
			||||||
            <a href="{% url 'place_detail' pk=place.pk %}" class="LP-Link">
 | 
					            {% include 'partials/place_teaser.html' with place=place%}
 | 
				
			||||||
                {% include 'partials/place_teaser.html' with place=place%}
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        {% endfor %}
 | 
					        {% endfor %}
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								django_lostplaces/lostplaces/templates/osm_map_full.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								django_lostplaces/lostplaces/templates/osm_map_full.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					{% extends 'global.html'%}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% load static %}
 | 
				
			||||||
 | 
					{% load i18n %}
 | 
				
			||||||
 | 
					{% block additional_head %}
 | 
				
			||||||
 | 
					<link rel="stylesheet" href="{% static 'maps/ol.css' %}" type="text/css">
 | 
				
			||||||
 | 
					<script src="{% static 'maps/ol.js' %}"></script>
 | 
				
			||||||
 | 
					{% endblock additional_head %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# {% block title %}{% trans 'Map' %}{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block maincontent %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% include 'partials/osm_map.html' with config=mapping_config modifier='full' %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% endblock maincontent %}
 | 
				
			||||||
@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					{%load static %}
 | 
				
			||||||
 | 
					{% load i18n %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% if request.user %}
 | 
				
			||||||
 | 
					{% if place in request.user.explorer.favorite_places.all %}
 | 
				
			||||||
 | 
					<a href="{% url 'place_unfavorite' place_id=place.id %}" class="LP-Link" title="{% trans 'Remove from favorites' %}">
 | 
				
			||||||
 | 
					    <img class="LP-Icon" src="{% static '/icons/favorite_filled.svg' %}" />
 | 
				
			||||||
 | 
					</a>
 | 
				
			||||||
 | 
					{%else%}
 | 
				
			||||||
 | 
					<a href="{% url 'place_favorite' place_id=place.id %}" class="LP-Link" title="{% trans 'Save as favorite' %}">
 | 
				
			||||||
 | 
					    <img class="LP-Icon" src="{% static '/icons/favorite.svg' %}" />
 | 
				
			||||||
 | 
					</a>
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					{%load static %}
 | 
				
			||||||
 | 
					{% load i18n %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% if request.user %}
 | 
				
			||||||
 | 
					{% if place in request.user.explorer.visited_places.all %}
 | 
				
			||||||
 | 
					<a href="{% url 'place_visit_delete' place_id=place.id %}" class="LP-Link" title="{% trans 'Remove from visits' %}">
 | 
				
			||||||
 | 
					    <img class="LP-Icon" src="{% static '/icons/pin_filled.svg' %}" />
 | 
				
			||||||
 | 
					</a>
 | 
				
			||||||
 | 
					{%else%}
 | 
				
			||||||
 | 
					<a href="{% url 'place_visit_create' place_id=place.id %}" class="LP-Link" title="{% trans 'Save as visited' %}">
 | 
				
			||||||
 | 
					    <img class="LP-Icon" src="{% static '/icons/pin.svg' %}" />
 | 
				
			||||||
 | 
					</a>
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
 | 
					{% endif %}
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
{% load static %}
 | 
					{% load static %}
 | 
				
			||||||
<div tabindex="1" id="map" class="LP-Map map" style="height: 300px"></div>
 | 
					<div tabindex="1" id="map" class="LP-Map {% if modifier %}LP-Map--{{modifier}}{% endif %} map"></div>
 | 
				
			||||||
    <div id="info" class="map-popup LP-Map__Popup"></div>
 | 
					    <div id="info" class="map-popup LP-Map__Popup"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <script type="text/javascript">
 | 
					        <script type="text/javascript">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,15 @@
 | 
				
			|||||||
{%load static %}
 | 
					{%load static %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<article class="LP-PlaceTeaser {% if extended %} LP-PlaceTeaser--extended{% endif %}">
 | 
					<article class="LP-PlaceTeaser {% if extended %} LP-PlaceTeaser--extended{% endif %}">
 | 
				
			||||||
    <div class="LP-PlaceTeaser__Image">
 | 
					    <a href="{% url 'place_detail' pk=place.pk %}" class="LP-Link">
 | 
				
			||||||
        {% if place.placeimages.all|length > 0 %}
 | 
					        <div class="LP-PlaceTeaser__Image">
 | 
				
			||||||
 | 
					            {% if place.placeimages.all|length > 0 %}
 | 
				
			||||||
            <img class="LP-Image" src="{{ place.placeimages.first.filename.thumbnail.url}}" />
 | 
					            <img class="LP-Image" src="{{ place.placeimages.first.filename.thumbnail.url}}" />
 | 
				
			||||||
        {% else %}
 | 
					            {% else %}
 | 
				
			||||||
            <img class="LP-Image" src="{% static 'images/missing_image.png' %}" />
 | 
					            <img class="LP-Image" src="{% static 'images/missing_image.png' %}" />
 | 
				
			||||||
        {% endif %}
 | 
					            {% endif %}
 | 
				
			||||||
    </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					    </a>
 | 
				
			||||||
    <div class="LP-PlaceTeaser__Meta">
 | 
					    <div class="LP-PlaceTeaser__Meta">
 | 
				
			||||||
        <div class="LP-PlaceTeaser__Info">
 | 
					        <div class="LP-PlaceTeaser__Info">
 | 
				
			||||||
            <span class="LP-PlaceTeaser__Title">
 | 
					            <span class="LP-PlaceTeaser__Title">
 | 
				
			||||||
@@ -20,16 +22,16 @@
 | 
				
			|||||||
        <div class="LP-PlaceTeaser__Description">
 | 
					        <div class="LP-PlaceTeaser__Description">
 | 
				
			||||||
            <p class="LP-Paragraph">
 | 
					            <p class="LP-Paragraph">
 | 
				
			||||||
                {% if place.description|length > 210 %}
 | 
					                {% if place.description|length > 210 %}
 | 
				
			||||||
                    {{place.description|truncatechars:210|truncatewords:-1}}
 | 
					                {{place.description|truncatechars:210|truncatewords:-1}}
 | 
				
			||||||
                {% else %}
 | 
					                {% else %}
 | 
				
			||||||
                    {{place.description}}
 | 
					                {{place.description}}
 | 
				
			||||||
                {% endif %}
 | 
					                {% endif %}
 | 
				
			||||||
            </p>
 | 
					            </p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="LP-PlaceTeaser__Icons">
 | 
					        <div class="LP-PlaceTeaser__Icons">
 | 
				
			||||||
            <ul class="LP-Icon__List">
 | 
					            <ul class="LP-Icon__List">
 | 
				
			||||||
                <li class="LP-Icon__Item"><img class="LP-Icon" src="{% static '/icons/favourite.svg' %}" /></li>
 | 
					                <li class="LP-Icon__Item">{% include 'partials/icons/place_favorite.html' with place=place%}</li>
 | 
				
			||||||
                <li class="LP-Icon__Item"><img class="LP-Icon" src="{% static '/icons/location.svg' %}" /></li>
 | 
					                <li class="LP-Icon__Item">{% include 'partials/icons/place_visited.html' with place=place%}</li>
 | 
				
			||||||
                <li class="LP-Icon__Item"><img class="LP-Icon" src="{% static '/icons/flag.svg' %}" /></li>
 | 
					                <li class="LP-Icon__Item"><img class="LP-Icon" src="{% static '/icons/flag.svg' %}" /></li>
 | 
				
			||||||
            </ul>
 | 
					            </ul>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@
 | 
				
			|||||||
<article class="LP-PlaceDetail">
 | 
					<article class="LP-PlaceDetail">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <header class="LP-PlaceDetail__Header">
 | 
					    <header class="LP-PlaceDetail__Header">
 | 
				
			||||||
        <h1 class="LP-Headline">{{ place.name }}</h1>
 | 
					        <h1 class="LP-Headline">{{ place.name }} {% include 'partials/icons/place_favorite.html' %} {% include 'partials/icons/place_visited.html' %}</h1>
 | 
				
			||||||
        {% if place.placeimages.first.filename.hero.url %}
 | 
					        {% if place.placeimages.first.filename.hero.url %}
 | 
				
			||||||
        <figure class="LP-PlaceDetail__Image">
 | 
					        <figure class="LP-PlaceDetail__Image">
 | 
				
			||||||
            <img src="{{ place.placeimages.first.filename.hero.url }}" class="LP-Image" />
 | 
					            <img src="{{ place.placeimages.first.filename.hero.url }}" class="LP-Image" />
 | 
				
			||||||
@@ -44,7 +44,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    <section class="LP-Section">
 | 
					    <section class="LP-Section">
 | 
				
			||||||
        <h1 class="LP-Headline">{% trans 'Map links' %}</h1>
 | 
					        <h1 class="LP-Headline">{% trans 'Map links' %}</h1>
 | 
				
			||||||
        {% include 'partials/osm_map.html' with config=mapping_config%}
 | 
					        {% include 'partials/osm_map.html' with config=mapping_config modifier='wide' %}
 | 
				
			||||||
        <div class="LP-LinkList">
 | 
					        <div class="LP-LinkList">
 | 
				
			||||||
            <ul class="LP-LinkList__Container">
 | 
					            <ul class="LP-LinkList__Container">
 | 
				
			||||||
                <li class="LP-LinkList__Item"><a target="_blank" href="https://www.google.com/maps?q={{place.latitude|safe}},{{place.longitude|safe}}" class="LP-Link"><span class="LP-Text">Google Maps</span></a></li>
 | 
					                <li class="LP-LinkList__Item"><a target="_blank" href="https://www.google.com/maps?q={{place.latitude|safe}},{{place.longitude|safe}}" class="LP-Link"><span class="LP-Text">Google Maps</span></a></li>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,15 +11,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
{% block maincontent %}
 | 
					{% block maincontent %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% include 'partials/osm_map.html' with config=mapping_config %}
 | 
					{% include 'partials/osm_map.html' with config=mapping_config modifier='wide' %}
 | 
				
			||||||
<div class="LP-PlaceList">
 | 
					<div class="LP-PlaceList">
 | 
				
			||||||
    <h1 class="LP-Headline">{% trans 'Our lost places' %}</h1>
 | 
					    <h1 class="LP-Headline">{% trans 'Our lost places' %}</h1>
 | 
				
			||||||
    <ul class="LP-PlaceList__List">
 | 
					    <ul class="LP-PlaceList__List">
 | 
				
			||||||
        {% for place in place_list %}
 | 
					        {% for place in place_list %}
 | 
				
			||||||
        <li class="LP-PlaceList__Item">
 | 
					        <li class="LP-PlaceList__Item">
 | 
				
			||||||
            <a href="{% url 'place_detail' pk=place.pk %}" class="LP-Link">
 | 
					            {% include 'partials/place_teaser.html' with place=place extended=True %}
 | 
				
			||||||
                {% include 'partials/place_teaser.html' with place=place extended=True %}
 | 
					 | 
				
			||||||
            </a>
 | 
					 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        {% endfor %}
 | 
					        {% endfor %}
 | 
				
			||||||
    </ul>
 | 
					    </ul>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,14 @@
 | 
				
			|||||||
                {% include 'partials/form/inputField.html' with field=form.email %}
 | 
					                {% include 'partials/form/inputField.html' with field=form.email %}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="LP-Form__Composition LP-Form__Composition--breakable">
 | 
				
			||||||
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 | 
					                {% include 'partials/form/inputField.html' with field=form.first_name %}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 | 
					                {% include 'partials/form/inputField.html' with field=form.last_name %}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <div class="LP-Form__Composition">
 | 
					        <div class="LP-Form__Composition">
 | 
				
			||||||
            <div class="LP-Form__Field">
 | 
					            <div class="LP-Form__Field">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,15 +4,15 @@ from django import forms
 | 
				
			|||||||
from django.utils import timezone
 | 
					from django.utils import timezone
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lostplaces.tests.forms import FormTestCase
 | 
					from lostplaces.tests.forms import FormTestCase
 | 
				
			||||||
from lostplaces.forms import ExplorerCreationForm
 | 
					from lostplaces.forms import SignupVoucherForm
 | 
				
			||||||
from lostplaces.models.models import Voucher
 | 
					from lostplaces.models.models import Voucher
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ExplorerCreationFormTestCase(FormTestCase):
 | 
					class SignupVoucherFormTestCase(FormTestCase):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    This test case only tests for the voucher since all other aspects don't realy matter
 | 
					    This test case only tests for the voucher since all other aspects don't realy matter
 | 
				
			||||||
    to this project and are already tested by django
 | 
					    to this project and are already tested by django
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    form = ExplorerCreationForm
 | 
					    form = SignupVoucherForm
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def setUpTestData(cls):
 | 
					    def setUpTestData(cls):
 | 
				
			||||||
@@ -37,7 +37,7 @@ class ExplorerCreationFormTestCase(FormTestCase):
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    def test_validation_valid(self):
 | 
					    def test_validation_valid(self):
 | 
				
			||||||
        form = ExplorerCreationForm(self.post_data)
 | 
					        form = SignupVoucherForm(self.post_data)
 | 
				
			||||||
        self.assertTrue(
 | 
					        self.assertTrue(
 | 
				
			||||||
            form.is_valid(),
 | 
					            form.is_valid(),
 | 
				
			||||||
            msg='Expecting the %s to validate' % (
 | 
					            msg='Expecting the %s to validate' % (
 | 
				
			||||||
@@ -49,7 +49,7 @@ class ExplorerCreationFormTestCase(FormTestCase):
 | 
				
			|||||||
        self.post_data = {
 | 
					        self.post_data = {
 | 
				
			||||||
            'voucher': 'Imanotacode123'
 | 
					            'voucher': 'Imanotacode123'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        form = ExplorerCreationForm(self.post_data)
 | 
					        form = SignupVoucherForm(self.post_data)
 | 
				
			||||||
        self.assertFalse(
 | 
					        self.assertFalse(
 | 
				
			||||||
            form.is_valid(),
 | 
					            form.is_valid(),
 | 
				
			||||||
            msg='Expecting the %s to not validate' % (
 | 
					            msg='Expecting the %s to not validate' % (
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,8 @@
 | 
				
			|||||||
from django.urls import path
 | 
					from django.urls import path
 | 
				
			||||||
from lostplaces.views import (
 | 
					from lostplaces.views import (
 | 
				
			||||||
    HomeView, 
 | 
					    HomeView, 
 | 
				
			||||||
 | 
					    FlatView,
 | 
				
			||||||
 | 
					    OSMMapView,
 | 
				
			||||||
    PlaceDetailView, 
 | 
					    PlaceDetailView, 
 | 
				
			||||||
    PlaceListView, 
 | 
					    PlaceListView, 
 | 
				
			||||||
    PlaceCreateView,
 | 
					    PlaceCreateView,
 | 
				
			||||||
@@ -11,30 +13,41 @@ from lostplaces.views import (
 | 
				
			|||||||
    PlaceDeleteView,
 | 
					    PlaceDeleteView,
 | 
				
			||||||
    PlaceTagDeleteView,
 | 
					    PlaceTagDeleteView,
 | 
				
			||||||
	PlaceTagSubmitView,
 | 
						PlaceTagSubmitView,
 | 
				
			||||||
	PhotoAlbumCreateView,
 | 
					    PlaceFavoriteView,
 | 
				
			||||||
	PhotoAlbumDeleteView,
 | 
					    PlaceUnfavoriteView,
 | 
				
			||||||
 | 
					    PlaceVisitCreateView,
 | 
				
			||||||
 | 
					    PlaceVisitDeleteView,
 | 
				
			||||||
    PlaceImageCreateView,
 | 
					    PlaceImageCreateView,
 | 
				
			||||||
    PlaceImageDeleteView,
 | 
					    PlaceImageDeleteView,
 | 
				
			||||||
    FlatView,
 | 
					    PhotoAlbumCreateView,
 | 
				
			||||||
    ExplorerProfileView
 | 
						PhotoAlbumDeleteView,
 | 
				
			||||||
 | 
					    ExplorerProfileView,
 | 
				
			||||||
 | 
					    ExplorerProfileUpdateView
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
urlpatterns = [
 | 
					urlpatterns = [
 | 
				
			||||||
    path('', HomeView.as_view(), name='lostplaces_home'),
 | 
					    path('', HomeView.as_view(), name='lostplaces_home'),
 | 
				
			||||||
 | 
					    path('flat/<slug:slug>/', FlatView, name='flatpage'),
 | 
				
			||||||
 | 
					    path('osm/', OSMMapView.as_view(), name='osm'),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    path('explorer/<int:explorer_id>/', ExplorerProfileView.as_view(), name='explorer_profile'),
 | 
				
			||||||
 | 
					    path('explorer/update/', ExplorerProfileUpdateView.as_view(), name='explorer_profile_update'),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    path('place/', PlaceListView.as_view(), name='place_list'),
 | 
				
			||||||
    path('place/<int:pk>/', PlaceDetailView.as_view(), name='place_detail'),
 | 
					    path('place/<int:pk>/', PlaceDetailView.as_view(), name='place_detail'),
 | 
				
			||||||
    path('place/create/', PlaceCreateView.as_view(), name='place_create'),
 | 
					    path('place/create/', PlaceCreateView.as_view(), name='place_create'),
 | 
				
			||||||
	path('photo_album/create/<int:place_id>', PhotoAlbumCreateView.as_view(), name='photo_album_create'),
 | 
					 | 
				
			||||||
	path('photo_album/delete/<int:pk>', PhotoAlbumDeleteView.as_view(), name='photo_album_delete'),
 | 
					 | 
				
			||||||
    path('place/update/<int:pk>/', PlaceUpdateView.as_view(), name='place_edit'),
 | 
					    path('place/update/<int:pk>/', PlaceUpdateView.as_view(), name='place_edit'),
 | 
				
			||||||
    path('place/delete/<int:pk>/', PlaceDeleteView.as_view(), name='place_delete'),
 | 
					    path('place/delete/<int:pk>/', PlaceDeleteView.as_view(), name='place_delete'),
 | 
				
			||||||
    path('place/', PlaceListView.as_view(), name='place_list'),
 | 
						path('place/tag/create/<int:tagged_id>/', PlaceTagSubmitView.as_view(), name='place_tag_submit'),
 | 
				
			||||||
    path('place_image/create/<int:place_id>', PlaceImageCreateView.as_view(), name='place_image_create'),
 | 
					    path('place/tag/delete/<int:tagged_id>/<int:tag_id>/', PlaceTagDeleteView.as_view(), name='place_tag_delete'),
 | 
				
			||||||
    path('place_image/delete/<int:pk>', PlaceImageDeleteView.as_view(), name='place_image_delete'),
 | 
					    path('place/fav/create/<int:place_id>/', PlaceFavoriteView.as_view(), name='place_favorite'),
 | 
				
			||||||
    path('flat/<slug:slug>/', FlatView, name='flatpage'),
 | 
					    path('place/fav/delete/<int:place_id>/', PlaceUnfavoriteView.as_view(), name='place_unfavorite'),
 | 
				
			||||||
 | 
					    path('place/visit/create/<int:place_id>/', PlaceVisitCreateView.as_view(), name='place_visit_create'),
 | 
				
			||||||
 | 
					    path('place/visit/delete/<int:place_id>/', PlaceVisitDeleteView.as_view(), name='place_visit_delete'),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # POST-only URLs for tag submission
 | 
					    path('place_image/create/<int:place_id>/', PlaceImageCreateView.as_view(), name='place_image_create'),
 | 
				
			||||||
	path('place/tag/<int:tagged_id>', PlaceTagSubmitView.as_view(), name='place_tag_submit'),
 | 
					    path('place_image/delete/<int:pk>/', PlaceImageDeleteView.as_view(), name='place_image_delete'),
 | 
				
			||||||
    path('place/tag/delete/<int:tagged_id>/<int:tag_id>', PlaceTagDeleteView.as_view(), name='place_tag_delete'),
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    path('explorer/<int:explorer_id>/', ExplorerProfileView.as_view(), name='explorer_profile')
 | 
						path('photo_album/create/<int:place_id>/', PhotoAlbumCreateView.as_view(), name='photo_album_create'),
 | 
				
			||||||
 | 
						path('photo_album/delete/<int:pk>/', PhotoAlbumDeleteView.as_view(), name='photo_album_delete')
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,10 +10,11 @@ from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
 | 
				
			|||||||
from django.contrib.messages.views import SuccessMessageMixin
 | 
					from django.contrib.messages.views import SuccessMessageMixin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.shortcuts import redirect, get_object_or_404
 | 
					from django.shortcuts import redirect, get_object_or_404
 | 
				
			||||||
from django.urls import reverse_lazy
 | 
					from django.urls import reverse_lazy, reverse
 | 
				
			||||||
from django.utils.translation import ugettext_lazy as _
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lostplaces.models import Place
 | 
					from lostplaces.models import Place
 | 
				
			||||||
 | 
					from lostplaces.common import redirect_referer_or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IsAuthenticatedMixin(LoginRequiredMixin, View):
 | 
					class IsAuthenticatedMixin(LoginRequiredMixin, View):
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
@@ -108,4 +109,4 @@ class PlaceAssetDeleteView(IsAuthenticatedMixin, IsPlaceSubmitterMixin, SingleOb
 | 
				
			|||||||
        place_id = self.get_object().place.id
 | 
					        place_id = self.get_object().place.id
 | 
				
			||||||
        self.get_object().delete()
 | 
					        self.get_object().delete()
 | 
				
			||||||
        messages.success(self.request, self.success_message)
 | 
					        messages.success(self.request, self.success_message)
 | 
				
			||||||
        return redirect(reverse_lazy('place_detail', kwargs={'pk': place_id}))
 | 
					        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place_id}))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,16 +7,18 @@ from django.utils.translation import ugettext_lazy as _
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from django.shortcuts import render, redirect, get_object_or_404
 | 
					from django.shortcuts import render, redirect, get_object_or_404
 | 
				
			||||||
from django.urls import reverse_lazy
 | 
					from django.urls import reverse_lazy
 | 
				
			||||||
 | 
					from django.contrib import messages
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lostplaces.common import get_all_subclasses
 | 
					from lostplaces.common import get_all_subclasses
 | 
				
			||||||
from lostplaces.views.base_views import IsAuthenticatedMixin
 | 
					from lostplaces.views.base_views import IsAuthenticatedMixin
 | 
				
			||||||
from lostplaces.models.models import Explorer
 | 
					from lostplaces.models.models import Explorer
 | 
				
			||||||
from lostplaces.models.place import Place, PlaceAsset
 | 
					from lostplaces.models.place import Place, PlaceAsset
 | 
				
			||||||
 | 
					from lostplaces.forms import ExplorerChangeForm, ExplorerUserChangeForm
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ExplorerProfileView(IsAuthenticatedMixin, View):
 | 
					class ExplorerProfileView(IsAuthenticatedMixin, View):
 | 
				
			||||||
    def get(self, request, explorer_id):
 | 
					    def get(self, request, explorer_id):
 | 
				
			||||||
        explorer = get_object_or_404(Explorer, pk=explorer_id)
 | 
					        explorer = get_object_or_404(Explorer, pk=explorer_id)
 | 
				
			||||||
        place_list = Place.objects.filter(submitted_by=explorer)
 | 
					        place_list = explorer.places.all()
 | 
				
			||||||
        place_count = place_list.count()
 | 
					        place_count = place_list.count()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        context={
 | 
					        context={
 | 
				
			||||||
@@ -34,12 +36,52 @@ class ExplorerProfileView(IsAuthenticatedMixin, View):
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
        context['asset_count'] = asset_count
 | 
					        context['asset_count'] = asset_count
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
        print(context['assets'])
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        return render(
 | 
					        return render(
 | 
				
			||||||
            request=request,
 | 
					            request=request,
 | 
				
			||||||
            template_name='explorer/profile.html',
 | 
					            template_name='explorer/profile.html',
 | 
				
			||||||
            context=context
 | 
					            context=context
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ExplorerProfileUpdateView(IsAuthenticatedMixin, View):
 | 
				
			||||||
 | 
					    success_message = ''
 | 
				
			||||||
 | 
					    permission_denied_message = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        context = {
 | 
				
			||||||
 | 
					            'explorer_user_change_form': ExplorerUserChangeForm(instance=request.user),
 | 
				
			||||||
 | 
					            'explorer_change_form': ExplorerChangeForm(instance=request.user.explorer)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if request.user.explorer.profile_image:
 | 
				
			||||||
 | 
					            context['explorer_image'] = request.user.explorer.profile_image
 | 
				
			||||||
 | 
					        return render(request, 'explorer/profile_update.html', context)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
 | 
					        print(request.POST)
 | 
				
			||||||
 | 
					        explorer_user_change_form = ExplorerUserChangeForm(
 | 
				
			||||||
 | 
					            request.POST,
 | 
				
			||||||
 | 
					            instance=request.user
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        explorer_change_form = ExplorerChangeForm(
 | 
				
			||||||
 | 
					            request.POST,
 | 
				
			||||||
 | 
					            request.FILES,
 | 
				
			||||||
 | 
					            instance=request.user.explorer
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if explorer_change_form.is_valid() and explorer_user_change_form.is_valid():
 | 
				
			||||||
 | 
					            explorer_user_change_form.save()
 | 
				
			||||||
 | 
					            explorer_change_form.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            print(explorer_change_form.cleaned_data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            messages.success(
 | 
				
			||||||
 | 
					                self.request,
 | 
				
			||||||
 | 
					                _('Successfully updated Explorer profile')
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            # Usually the browser should have checked the form before sending.
 | 
				
			||||||
 | 
					            messages.error(
 | 
				
			||||||
 | 
					                self.request,
 | 
				
			||||||
 | 
					                _('Please fill in all required fields.')
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        return redirect(reverse_lazy('explorer_profile_update'))
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@@ -13,12 +13,13 @@ from django.contrib.messages.views import SuccessMessageMixin
 | 
				
			|||||||
from django.utils.translation import ugettext_lazy as _
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.shortcuts import render, redirect, get_object_or_404
 | 
					from django.shortcuts import render, redirect, get_object_or_404
 | 
				
			||||||
from django.urls import reverse_lazy
 | 
					from django.urls import reverse_lazy, reverse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lostplaces.models import Place, PlaceImage
 | 
					from lostplaces.models import Place, PlaceImage
 | 
				
			||||||
from lostplaces.views.base_views import IsAuthenticatedMixin, IsPlaceSubmitterMixin
 | 
					from lostplaces.views.base_views import IsAuthenticatedMixin, IsPlaceSubmitterMixin
 | 
				
			||||||
from lostplaces.views.place_image_views import MultiplePlaceImageUploadMixin
 | 
					from lostplaces.views.place_image_views import MultiplePlaceImageUploadMixin
 | 
				
			||||||
from lostplaces.forms import PlaceForm, PlaceImageForm, TagSubmitForm
 | 
					from lostplaces.forms import PlaceForm, PlaceImageForm, TagSubmitForm
 | 
				
			||||||
 | 
					from lostplaces.common import redirect_referer_or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from taggit.models import Tag
 | 
					from taggit.models import Tag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -104,7 +105,14 @@ class PlaceCreateView(MultiplePlaceImageUploadMixin, IsAuthenticatedMixin, View)
 | 
				
			|||||||
                self.request,
 | 
					                self.request,
 | 
				
			||||||
                _('Please fill in all required fields.')
 | 
					                _('Please fill in all required fields.')
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            return render(request, 'place/place_create.html', context={'form': place_form})
 | 
					            return render(
 | 
				
			||||||
 | 
					                request=request,
 | 
				
			||||||
 | 
					                template_name='place/place_create.html',
 | 
				
			||||||
 | 
					                context={
 | 
				
			||||||
 | 
					                    'place_form': place_form,
 | 
				
			||||||
 | 
					                    'place_image_form': PlaceImageForm()
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlaceDeleteView(IsAuthenticatedMixin, IsPlaceSubmitterMixin, DeleteView):
 | 
					class PlaceDeleteView(IsAuthenticatedMixin, IsPlaceSubmitterMixin, DeleteView):
 | 
				
			||||||
    template_name = 'place/place_delete.html'
 | 
					    template_name = 'place/place_delete.html'
 | 
				
			||||||
@@ -119,3 +127,43 @@ class PlaceDeleteView(IsAuthenticatedMixin, IsPlaceSubmitterMixin, DeleteView):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def get_place(self):
 | 
					    def get_place(self):
 | 
				
			||||||
        return self.get_object()
 | 
					        return self.get_object()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PlaceFavoriteView(IsAuthenticatedMixin, View):
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def get(self, request, place_id):
 | 
				
			||||||
 | 
					        place = get_object_or_404(Place, id=place_id)
 | 
				
			||||||
 | 
					        if request.user is not None:
 | 
				
			||||||
 | 
					            request.user.explorer.favorite_places.add(place)
 | 
				
			||||||
 | 
					            request.user.explorer.save()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					class PlaceUnfavoriteView(IsAuthenticatedMixin, View):
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def get(self, request, place_id):
 | 
				
			||||||
 | 
					        place = get_object_or_404(Place, id=place_id)
 | 
				
			||||||
 | 
					        if request.user is not None:
 | 
				
			||||||
 | 
					            request.user.explorer.favorite_places.remove(place)
 | 
				
			||||||
 | 
					            request.user.explorer.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))                    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PlaceVisitCreateView(IsAuthenticatedMixin, View):
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def get(self, request, place_id):
 | 
				
			||||||
 | 
					        place = get_object_or_404(Place, id=place_id)
 | 
				
			||||||
 | 
					        if request.user is not None:
 | 
				
			||||||
 | 
					            request.user.explorer.visited_places.add(place)
 | 
				
			||||||
 | 
					            request.user.explorer.save()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					class PlaceVisitDeleteView(IsAuthenticatedMixin, View):
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def get(self, request, place_id):
 | 
				
			||||||
 | 
					        place = get_object_or_404(Place, id=place_id)
 | 
				
			||||||
 | 
					        if request.user is not None:
 | 
				
			||||||
 | 
					            request.user.explorer.visited_places.remove(place)
 | 
				
			||||||
 | 
					            request.user.explorer.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))                    
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,14 +6,15 @@ from django.views.generic.edit import CreateView
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from django.contrib.messages.views import SuccessMessageMixin
 | 
					from django.contrib.messages.views import SuccessMessageMixin
 | 
				
			||||||
from django.contrib import messages
 | 
					from django.contrib import messages
 | 
				
			||||||
from django.urls import reverse_lazy
 | 
					from django.urls import reverse_lazy, reverse
 | 
				
			||||||
from django.shortcuts import render, redirect, get_object_or_404
 | 
					from django.shortcuts import render, redirect, get_object_or_404
 | 
				
			||||||
from django.http import HttpResponseForbidden
 | 
					from django.http import HttpResponseForbidden
 | 
				
			||||||
from django.utils.translation import ugettext_lazy as _
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lostplaces.forms import ExplorerCreationForm, TagSubmitForm
 | 
					from lostplaces.forms import SignupVoucherForm, TagSubmitForm
 | 
				
			||||||
from lostplaces.models import Place, PhotoAlbum
 | 
					from lostplaces.models import Place, PhotoAlbum
 | 
				
			||||||
from lostplaces.views.base_views import IsAuthenticatedMixin
 | 
					from lostplaces.views.base_views import IsAuthenticatedMixin
 | 
				
			||||||
 | 
					from lostplaces.common import redirect_referer_or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from lostplaces.views.base_views import (
 | 
					from lostplaces.views.base_views import (
 | 
				
			||||||
    PlaceAssetCreateView, 
 | 
					    PlaceAssetCreateView, 
 | 
				
			||||||
@@ -23,7 +24,7 @@ from lostplaces.views.base_views import (
 | 
				
			|||||||
from taggit.models import Tag
 | 
					from taggit.models import Tag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SignUpView(SuccessMessageMixin, CreateView):
 | 
					class SignUpView(SuccessMessageMixin, CreateView):
 | 
				
			||||||
    form_class = ExplorerCreationForm
 | 
					    form_class = SignupVoucherForm
 | 
				
			||||||
    success_url = reverse_lazy('login')
 | 
					    success_url = reverse_lazy('login')
 | 
				
			||||||
    template_name = 'signup.html'
 | 
					    template_name = 'signup.html'
 | 
				
			||||||
    success_message = _('User created')
 | 
					    success_message = _('User created')
 | 
				
			||||||
@@ -79,10 +80,22 @@ class PlaceTagDeleteView(IsAuthenticatedMixin, View):
 | 
				
			|||||||
        place = get_object_or_404(Place, pk=tagged_id)
 | 
					        place = get_object_or_404(Place, pk=tagged_id)
 | 
				
			||||||
        tag = get_object_or_404(Tag, pk=tag_id)
 | 
					        tag = get_object_or_404(Tag, pk=tag_id)
 | 
				
			||||||
        place.tags.remove(tag)
 | 
					        place.tags.remove(tag)
 | 
				
			||||||
        return redirect(reverse_lazy('place_detail', kwargs={'pk': tagged_id}))
 | 
					        
 | 
				
			||||||
 | 
					        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': tagged_id}))                    
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
def FlatView(request, slug):
 | 
					def FlatView(request, slug):
 | 
				
			||||||
    if request.LANGUAGE_CODE == 'de':
 | 
					    if request.LANGUAGE_CODE == 'de':
 | 
				
			||||||
        return render(request, 'flat/' + slug + '-de' + '.html')
 | 
					        return render(request, 'flat/' + slug + '-de' + '.html')
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return render(request, 'flat/' + slug + '.html')
 | 
					        return render(request, 'flat/' + slug + '.html')
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					class OSMMapView(IsAuthenticatedMixin, View):
 | 
				
			||||||
 | 
					    def get(self, request):
 | 
				
			||||||
 | 
					        place_list = Place.objects.all()
 | 
				
			||||||
 | 
					        context = {
 | 
				
			||||||
 | 
					            'mapping_config': {
 | 
				
			||||||
 | 
					                'all_points': place_list,
 | 
				
			||||||
 | 
					                'map_center': Place.average_latlon(place_list)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return render(request, 'osm_map_full.html', context)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user