Merge remote-tracking branch 'origin/develop' into feature/50-Linktypes
This commit is contained in:
		
							
								
								
									
										1
									
								
								Pipfile
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								Pipfile
									
									
									
									
									
								
							@@ -13,6 +13,7 @@ twine = "*"
 | 
				
			|||||||
pandoc = "*"
 | 
					pandoc = "*"
 | 
				
			||||||
pylint-django = "*"
 | 
					pylint-django = "*"
 | 
				
			||||||
setuptools = "*"
 | 
					setuptools = "*"
 | 
				
			||||||
 | 
					django-nose = "*"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[packages]
 | 
					[packages]
 | 
				
			||||||
django = "*"
 | 
					django = "*"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,7 +49,15 @@ INSTALLED_APPS = [
 | 
				
			|||||||
    'django.contrib.contenttypes',
 | 
					    'django.contrib.contenttypes',
 | 
				
			||||||
    'django.contrib.sessions',
 | 
					    'django.contrib.sessions',
 | 
				
			||||||
    'django.contrib.messages',
 | 
					    'django.contrib.messages',
 | 
				
			||||||
    'django.contrib.staticfiles'
 | 
					    'django.contrib.staticfiles',
 | 
				
			||||||
 | 
					    'django_nose'
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NOSE_ARGS = [
 | 
				
			||||||
 | 
					    '--with-coverage',
 | 
				
			||||||
 | 
					    '--cover-package=lostplaces',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MIDDLEWARE = [
 | 
					MIDDLEWARE = [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ from django.conf import settings
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
settings.THUMBNAIL_ALIASES = {
 | 
					settings.THUMBNAIL_ALIASES = {
 | 
				
			||||||
    '': {
 | 
					    '': {
 | 
				
			||||||
        'thumbnail': {'size': (300, 200), 'sharpen': True, 'crop': True},
 | 
					        'thumbnail': {'size': (300, 200), 'sharpen': True, 'crop': True, 'upscale': True},
 | 
				
			||||||
        'hero': {'size': (700, 466), 'sharpen': True, 'crop': True},
 | 
					        'hero': {'size': (700, 466), 'sharpen': True, 'crop': True},
 | 
				
			||||||
        'large': {'size': (1920, 1920), 'sharpen': True, 'crop': False},
 | 
					        'large': {'size': (1920, 1920), 'sharpen': True, 'crop': False},
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,4 +4,5 @@
 | 
				
			|||||||
from django.apps import AppConfig
 | 
					from django.apps import AppConfig
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class LostplacesAppConfig(AppConfig):
 | 
					class LostplacesAppConfig(AppConfig):
 | 
				
			||||||
 | 
					    default_auto_field = 'django.db.models.AutoField'
 | 
				
			||||||
    name = 'lostplaces'
 | 
					    name = 'lostplaces'
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -82,6 +82,18 @@ class Explorer(models.Model):
 | 
				
			|||||||
        choices=EXPLORER_LEVELS
 | 
					        choices=EXPLORER_LEVELS
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_places_eligible_to_see(self):
 | 
				
			||||||
 | 
					        if self.user.is_superuser:
 | 
				
			||||||
 | 
					            return Place.objects.all()
 | 
				
			||||||
 | 
					        return Place.objects.all().filter(level__lte=self.level) | self.places.all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def is_eligible_to_see(self, place):
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            self.user.is_superuser or
 | 
				
			||||||
 | 
					            place.submitted_by == self or
 | 
				
			||||||
 | 
					            place in self.get_places_eligible_to_see()
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        return self.user.username
 | 
					        return self.user.username
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,9 +37,36 @@ class TestPlaceListView(GlobalTemplateTestCaseMixin, ViewTestCase):
 | 
				
			|||||||
    def setUpTestData(cls):
 | 
					    def setUpTestData(cls):
 | 
				
			||||||
        user = User.objects.create_user(
 | 
					        user = User.objects.create_user(
 | 
				
			||||||
            username='testpeter',
 | 
					            username='testpeter',
 | 
				
			||||||
 | 
					            password='Develop123',
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        user.explorer.level = 3
 | 
				
			||||||
 | 
					        user.explorer.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # default level should be 1, not setting required
 | 
				
			||||||
 | 
					        other_user = User.objects.create_user(
 | 
				
			||||||
 | 
					            username='blubberbernd',
 | 
				
			||||||
            password='Develop123'
 | 
					            password='Develop123'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        superuser = User.objects.create_user(
 | 
				
			||||||
 | 
					            username='toor',
 | 
				
			||||||
 | 
					            password='Develop123'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        superuser.is_superuser = True
 | 
				
			||||||
 | 
					        superuser.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Place.objects.create(
 | 
				
			||||||
 | 
					            name='Im a own place',
 | 
				
			||||||
 | 
					            submitted_when=timezone.now(),
 | 
				
			||||||
 | 
					            submitted_by=other_user.explorer,
 | 
				
			||||||
 | 
					            location='Test %d town' % 5,
 | 
				
			||||||
 | 
					            latitude=50.5 + 5/10,
 | 
				
			||||||
 | 
					            longitude=7.0 - 5/10,
 | 
				
			||||||
 | 
					            description='This is just a test, do not worry %d' % 5,
 | 
				
			||||||
 | 
					            level=3
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for i in range(12):
 | 
					        for i in range(12):
 | 
				
			||||||
            place = Place.objects.create(
 | 
					            place = Place.objects.create(
 | 
				
			||||||
                name='Im a place %d' % i,
 | 
					                name='Im a place %d' % i,
 | 
				
			||||||
@@ -48,7 +75,8 @@ class TestPlaceListView(GlobalTemplateTestCaseMixin, ViewTestCase):
 | 
				
			|||||||
                location='Test %d town' % i,
 | 
					                location='Test %d town' % i,
 | 
				
			||||||
                latitude=50.5 + i/10,
 | 
					                latitude=50.5 + i/10,
 | 
				
			||||||
                longitude=7.0 - i/10,
 | 
					                longitude=7.0 - i/10,
 | 
				
			||||||
                description='This is just a test, do not worry %d' % i
 | 
					                description='This is just a test, do not worry %d' % i,
 | 
				
			||||||
 | 
					                level=3
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        place.tags.add('I a tag', 'testlocation')
 | 
					        place.tags.add('I a tag', 'testlocation')
 | 
				
			||||||
        place.save()
 | 
					        place.save()
 | 
				
			||||||
@@ -90,6 +118,42 @@ class TestPlaceListView(GlobalTemplateTestCaseMixin, ViewTestCase):
 | 
				
			|||||||
            ),
 | 
					            ),
 | 
				
			||||||
            msg='Expecting the place list to be paginated like [first] [previous] [item] at least 2 times [next] [last]'
 | 
					            msg='Expecting the place list to be paginated like [first] [previous] [item] at least 2 times [next] [last]'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_not_eligible_to_see_because_of_low_level(self):
 | 
				
			||||||
 | 
					        self.client.login(username='blubberbernd', password='Develop123')
 | 
				
			||||||
 | 
					        response = self.client.get(reverse('place_list'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertFalse(
 | 
				
			||||||
 | 
					            'Im a place' in response.content.decode(),
 | 
				
			||||||
 | 
					            msg='Expecting the user to not see any places'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_not_eligible_to_see_because_of_low_level_superuser(self):
 | 
				
			||||||
 | 
					        self.client.login(username='toor', password='Develop123')
 | 
				
			||||||
 | 
					        response = self.client.get(reverse('place_list'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            'Im a place' in response.content.decode(),
 | 
				
			||||||
 | 
					            msg='Expecting the superuser to see all places'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_not_eligible_to_see_because_of_low_level_own_place(self):
 | 
				
			||||||
 | 
					        self.client.login(username='blubberbernd', password='Develop123')
 | 
				
			||||||
 | 
					        response = self.client.get(reverse('place_list'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            'Im a own place' in response.content.decode(),
 | 
				
			||||||
 | 
					            msg='Expecting the user to see it\'s own places'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_eligible_to_see(self):
 | 
				
			||||||
 | 
					        self.client.login(username='testpeter', password='Develop123')
 | 
				
			||||||
 | 
					        response = self.client.get(reverse('place_list'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            'Im a own place' in response.content.decode(),
 | 
				
			||||||
 | 
					            msg='Expecting the user to see places where their level is high enough'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
class TestPlaceCreateView(ViewTestCase):
 | 
					class TestPlaceCreateView(ViewTestCase):
 | 
				
			||||||
    view = PlaceCreateView
 | 
					    view = PlaceCreateView
 | 
				
			||||||
@@ -308,6 +372,8 @@ class PlaceDetailViewTestCase(TaggableViewTestCaseMixin, MapableViewTestCaseMixi
 | 
				
			|||||||
            username='testpeter',
 | 
					            username='testpeter',
 | 
				
			||||||
            password='Develop123'
 | 
					            password='Develop123'
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					        user.explorer.level = 3
 | 
				
			||||||
 | 
					        user.explorer.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        place = Place.objects.create(
 | 
					        place = Place.objects.create(
 | 
				
			||||||
            name='Im a place',
 | 
					            name='Im a place',
 | 
				
			||||||
@@ -316,11 +382,72 @@ class PlaceDetailViewTestCase(TaggableViewTestCaseMixin, MapableViewTestCaseMixi
 | 
				
			|||||||
            location='Testtown',
 | 
					            location='Testtown',
 | 
				
			||||||
            latitude=50.5,
 | 
					            latitude=50.5,
 | 
				
			||||||
            longitude=7.0,
 | 
					            longitude=7.0,
 | 
				
			||||||
            description='This is just a test, do not worry'
 | 
					            description='This is just a test, do not worry',
 | 
				
			||||||
 | 
					            level=3
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        place.tags.add('I a tag', 'testlocation')
 | 
					        place.tags.add('I a tag', 'testlocation')
 | 
				
			||||||
        place.save()
 | 
					        place.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        other_user = User.objects.create_user(
 | 
				
			||||||
 | 
					            username='blubberbernd',
 | 
				
			||||||
 | 
					            password='Develop123'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        superuser = User.objects.create_user(
 | 
				
			||||||
 | 
					            username='toor',
 | 
				
			||||||
 | 
					            password='Develop123'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        superuser.is_superuser = True
 | 
				
			||||||
 | 
					        superuser.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Place.objects.create(
 | 
				
			||||||
 | 
					            name='Im a own place',
 | 
				
			||||||
 | 
					            submitted_when=timezone.now(),
 | 
				
			||||||
 | 
					            submitted_by=other_user.explorer,
 | 
				
			||||||
 | 
					            location='Test %d town' % 5,
 | 
				
			||||||
 | 
					            latitude=50.5 + 5/10,
 | 
				
			||||||
 | 
					            longitude=7.0 - 5/10,
 | 
				
			||||||
 | 
					            description='This is just a test, do not worry %d' % 5,
 | 
				
			||||||
 | 
					            level=3
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_not_eligible_to_see_because_of_low_level(self):
 | 
				
			||||||
 | 
					        self.client.login(username='blubberbernd', password='Develop123')
 | 
				
			||||||
 | 
					        response = self.client.get(reverse('place_detail', kwargs={'pk': 1}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertFalse(
 | 
				
			||||||
 | 
					            'Im a place' in response.content.decode(),
 | 
				
			||||||
 | 
					            msg='Expecting the user to not see the places'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_not_eligible_to_see_because_of_low_level_superuser(self):
 | 
				
			||||||
 | 
					        self.client.login(username='toor', password='Develop123')
 | 
				
			||||||
 | 
					        response = self.client.get(reverse('place_detail', kwargs={'pk': 1}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            'Im a place' in response.content.decode(),
 | 
				
			||||||
 | 
					            msg='Expecting the superuser to see all places'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_not_eligible_to_see_because_of_low_level_own_place(self):
 | 
				
			||||||
 | 
					        self.client.login(username='blubberbernd', password='Develop123')
 | 
				
			||||||
 | 
					        response = self.client.get(reverse('place_detail', kwargs={'pk': 2}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            'Im a own place' in response.content.decode(),
 | 
				
			||||||
 | 
					            msg='Expecting the user to see it\'s own places'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_eligible_to_see(self):
 | 
				
			||||||
 | 
					        self.client.login(username='testpeter', password='Develop123')
 | 
				
			||||||
 | 
					        response = self.client.get(reverse('place_detail', kwargs={'pk': 2}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.assertTrue(
 | 
				
			||||||
 | 
					            'Im a own place' in response.content.decode(),
 | 
				
			||||||
 | 
					            msg='Expecting the user to see places where their level is high enough'
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_not_authenticated(self):
 | 
					    def test_not_authenticated(self):
 | 
				
			||||||
        response = self.client.get(reverse('place_detail', kwargs={'pk': 1}))
 | 
					        response = self.client.get(reverse('place_detail', kwargs={'pk': 1}))
 | 
				
			||||||
        self.assertHttpRedirect(response)
 | 
					        self.assertHttpRedirect(response)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@
 | 
				
			|||||||
from django.views import View
 | 
					from django.views import View
 | 
				
			||||||
from django.views.generic.edit import CreateView
 | 
					from django.views.generic.edit import CreateView
 | 
				
			||||||
from django.views.generic.detail import SingleObjectMixin
 | 
					from django.views.generic.detail import SingleObjectMixin
 | 
				
			||||||
 | 
					from django.views.generic import ListView
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.contrib import messages
 | 
					from django.contrib import messages
 | 
				
			||||||
from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
 | 
					from django.contrib.auth.mixins import UserPassesTestMixin, LoginRequiredMixin
 | 
				
			||||||
@@ -26,7 +27,8 @@ class IsAuthenticatedMixin(LoginRequiredMixin, View):
 | 
				
			|||||||
    permission_denied_message = _('Please login to proceed')
 | 
					    permission_denied_message = _('Please login to proceed')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_no_permission(self):
 | 
					    def handle_no_permission(self):
 | 
				
			||||||
        messages.error(self.request, self.permission_denied_message)
 | 
					        if not self.request.user.is_authenticated:
 | 
				
			||||||
 | 
					            messages.error(self.request, self.permission_denied_message)
 | 
				
			||||||
        return super().handle_no_permission()
 | 
					        return super().handle_no_permission()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IsPlaceSubmitterMixin(UserPassesTestMixin, View):
 | 
					class IsPlaceSubmitterMixin(UserPassesTestMixin, View):
 | 
				
			||||||
@@ -60,6 +62,23 @@ class IsPlaceSubmitterMixin(UserPassesTestMixin, View):
 | 
				
			|||||||
            messages.error(self.request, self.place_submitter_error_message)
 | 
					            messages.error(self.request, self.place_submitter_error_message)
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class IsEligibleToSeePlaceMixin(UserPassesTestMixin):
 | 
				
			||||||
 | 
					    not_eligible_to_see_message = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_place(self):
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_func(self):
 | 
				
			||||||
 | 
					        if not hasattr(self.request, 'user'):
 | 
				
			||||||
 | 
					            return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.request.user.explorer.is_eligible_to_see(self.get_place()):
 | 
				
			||||||
 | 
					            return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.not_eligible_to_see_message:
 | 
				
			||||||
 | 
					            messages.error(self.request, self.not_eligible_to_see_message)
 | 
				
			||||||
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlaceAssetCreateView(IsAuthenticatedMixin, SuccessMessageMixin, CreateView):
 | 
					class PlaceAssetCreateView(IsAuthenticatedMixin, SuccessMessageMixin, CreateView):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    Abstract View for creating a place asset (i.e. PlaceImage) 
 | 
					    Abstract View for creating a place asset (i.e. PlaceImage) 
 | 
				
			||||||
@@ -113,3 +132,10 @@ class PlaceAssetDeleteView(IsAuthenticatedMixin, IsPlaceSubmitterMixin, SingleOb
 | 
				
			|||||||
        self.get_object().delete()
 | 
					        self.get_object().delete()
 | 
				
			||||||
        messages.success(self.request, self.success_message)
 | 
					        messages.success(self.request, self.success_message)
 | 
				
			||||||
        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place_id}))
 | 
					        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place_id}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LevelCapPlaceListView(ListView):
 | 
				
			||||||
 | 
					    model = Place
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def get_queryset(self):
 | 
				
			||||||
 | 
					        return self.request.user.explorer.get_places_eligible_to_see()
 | 
				
			||||||
@@ -18,7 +18,10 @@ class MultiplePlaceImageUploadMixin:
 | 
				
			|||||||
                    submitted_by=submitted_by
 | 
					                    submitted_by=submitted_by
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                place_image.save()
 | 
					                place_image.save()
 | 
				
			||||||
            
 | 
					            if place.hero is None:
 | 
				
			||||||
 | 
					                place.hero = place.placeimages.all()[0]
 | 
				
			||||||
 | 
					                place.save()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlaceImageCreateView(MultiplePlaceImageUploadMixin, PlaceAssetCreateView):
 | 
					class PlaceImageCreateView(MultiplePlaceImageUploadMixin, PlaceAssetCreateView):
 | 
				
			||||||
    model = PlaceImage
 | 
					    model = PlaceImage
 | 
				
			||||||
    form_class = PlaceImageForm
 | 
					    form_class = PlaceImageForm
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,6 @@ from django.db.models.functions import Lower
 | 
				
			|||||||
from django.views import View
 | 
					from django.views import View
 | 
				
			||||||
from django.views.generic.edit import CreateView, UpdateView, DeleteView
 | 
					from django.views.generic.edit import CreateView, UpdateView, DeleteView
 | 
				
			||||||
from django.views.generic.detail import SingleObjectMixin
 | 
					from django.views.generic.detail import SingleObjectMixin
 | 
				
			||||||
from django.views.generic import ListView
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from django.contrib import messages
 | 
					from django.contrib import messages
 | 
				
			||||||
from django.contrib.messages.views import SuccessMessageMixin
 | 
					from django.contrib.messages.views import SuccessMessageMixin
 | 
				
			||||||
@@ -16,16 +15,20 @@ from django.shortcuts import render, redirect, get_object_or_404
 | 
				
			|||||||
from django.urls import reverse_lazy, reverse
 | 
					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,
 | 
				
			||||||
 | 
					    LevelCapPlaceListView,
 | 
				
			||||||
 | 
					    IsEligibleToSeePlaceMixin
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
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 lostplaces.common import redirect_referer_or
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from taggit.models import Tag
 | 
					from taggit.models import Tag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlaceListView(IsAuthenticatedMixin, ListView):
 | 
					class PlaceListView(IsAuthenticatedMixin, LevelCapPlaceListView):
 | 
				
			||||||
    paginate_by = 5
 | 
					    paginate_by = 5
 | 
				
			||||||
    model = Place
 | 
					 | 
				
			||||||
    template_name = 'place/place_list.html'
 | 
					    template_name = 'place/place_list.html'
 | 
				
			||||||
    ordering = [Lower('name')]
 | 
					    ordering = [Lower('name')]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -37,9 +40,15 @@ class PlaceListView(IsAuthenticatedMixin, ListView):
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlaceDetailView(IsAuthenticatedMixin, View):
 | 
					class PlaceDetailView(IsAuthenticatedMixin, IsEligibleToSeePlaceMixin, View):
 | 
				
			||||||
    def get(self, request, pk):
 | 
					    not_eligible_to_see_message = _('You\'r not allowed to see this place')
 | 
				
			||||||
        place = get_object_or_404(Place, pk=pk)
 | 
					
 | 
				
			||||||
 | 
					    def get_place(self):
 | 
				
			||||||
 | 
					        return get_object_or_404(Place, pk=self.kwargs['pk'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get(self, request, pk):        
 | 
				
			||||||
 | 
					        place = self.get_place()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        context = {
 | 
					        context = {
 | 
				
			||||||
            'place': place,
 | 
					            'place': place,
 | 
				
			||||||
            'mapping_config': {
 | 
					            'mapping_config': {
 | 
				
			||||||
@@ -129,10 +138,14 @@ 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):
 | 
					class PlaceFavoriteView(IsAuthenticatedMixin, IsEligibleToSeePlaceMixin, View):
 | 
				
			||||||
    
 | 
					    not_eligible_to_see_message = _('You\'r not allowed to favorite this place')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_place(self):
 | 
				
			||||||
 | 
					        return get_object_or_404(Place, pk=self.kwargs['place_id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get(self, request, place_id):
 | 
					    def get(self, request, place_id):
 | 
				
			||||||
        place = get_object_or_404(Place, id=place_id)
 | 
					        place = self.get_place()
 | 
				
			||||||
        if request.user is not None:
 | 
					        if request.user is not None:
 | 
				
			||||||
            request.user.explorer.favorite_places.add(place)
 | 
					            request.user.explorer.favorite_places.add(place)
 | 
				
			||||||
            request.user.explorer.save()
 | 
					            request.user.explorer.save()
 | 
				
			||||||
@@ -140,7 +153,7 @@ class PlaceFavoriteView(IsAuthenticatedMixin, View):
 | 
				
			|||||||
        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))
 | 
					        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
class PlaceUnfavoriteView(IsAuthenticatedMixin, View):
 | 
					class PlaceUnfavoriteView(IsAuthenticatedMixin, View):
 | 
				
			||||||
    
 | 
					
 | 
				
			||||||
    def get(self, request, place_id):
 | 
					    def get(self, request, place_id):
 | 
				
			||||||
        place = get_object_or_404(Place, id=place_id)
 | 
					        place = get_object_or_404(Place, id=place_id)
 | 
				
			||||||
        if request.user is not None:
 | 
					        if request.user is not None:
 | 
				
			||||||
@@ -149,10 +162,14 @@ class PlaceUnfavoriteView(IsAuthenticatedMixin, View):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))                    
 | 
					        return redirect_referer_or(request, reverse('place_detail', kwargs={'pk': place.pk}))                    
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PlaceVisitCreateView(IsAuthenticatedMixin, View):
 | 
					class PlaceVisitCreateView(IsAuthenticatedMixin, IsEligibleToSeePlaceMixin, View):
 | 
				
			||||||
    
 | 
					    not_eligible_to_see_message = _('You\'r not allowed to visit this place :P (Now please stop trying out URL\'s)')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_place(self):
 | 
				
			||||||
 | 
					        return get_object_or_404(Place, pk=self.kwargs['place_id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get(self, request, place_id):
 | 
					    def get(self, request, place_id):
 | 
				
			||||||
        place = get_object_or_404(Place, id=place_id)
 | 
					        place = self.get_place()
 | 
				
			||||||
        if request.user is not None:
 | 
					        if request.user is not None:
 | 
				
			||||||
            request.user.explorer.visited_places.add(place)
 | 
					            request.user.explorer.visited_places.add(place)
 | 
				
			||||||
            request.user.explorer.save()
 | 
					            request.user.explorer.save()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ class SignUpView(SuccessMessageMixin, CreateView):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class HomeView(IsAuthenticatedMixin, View):
 | 
					class HomeView(IsAuthenticatedMixin, View):
 | 
				
			||||||
    def get(self, request, *args, **kwargs):
 | 
					    def get(self, request, *args, **kwargs):
 | 
				
			||||||
        place_list = Place.objects.all().order_by('-submitted_when')[:10]
 | 
					        place_list = request.user.explorer.get_places_eligible_to_see()
 | 
				
			||||||
        context = {
 | 
					        context = {
 | 
				
			||||||
            'place_list': place_list,
 | 
					            'place_list': place_list,
 | 
				
			||||||
            'mapping_config': {
 | 
					            'mapping_config': {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user