Exemple #1
0
def index(request):
    county_objects = County.typical_objects().exclude(code='21').order_by('code') # Exclude Svalbard

    # We'll use a "fake" county to represent the entire country, with a sentinel ID value
    fake_national_county = County(
        id='all',
        name='Hele landet',
    )

    # Prepend "entire country" to the county listing
    counties = [fake_national_county]
    counties.extend(county_objects)

    # Split the counties into groups pre-divided for 3 columns
    counties_three_columns = (
        [county for i, county in enumerate(counties) if i % 3 == 0],
        [county for i, county in enumerate(counties) if (i - 1) % 3 == 0],
        [county for i, county in enumerate(counties) if (i - 2) % 3 == 0],
    )

    context = {
        'categories': Forening.PUBLIC_CATEGORIES,
        'chosen_category': request.GET.get('kategori', 'foreninger').lower(),
        'counties': counties,
        'counties_three_columns': counties_three_columns,
        'chosen_county_name': request.GET.get('fylke', fake_national_county.name),
        'prerendered_select': render_forening_select(request),
    }
    return render(request, 'central/foreninger/list.html', context)
Exemple #2
0
def index(request):
    annonser, start_index, end = Annonse.get_by_filter(request.session.get('fjelltreffen.filter', {}))
    context = {
        'annonser': annonser,
        'start_index': start_index,
        'end': end,
        'counties': County.typical_objects(),
        'annonse_retention_days': settings.FJELLTREFFEN_ANNONSE_RETENTION_DAYS,
        'age_limits': settings.FJELLTREFFEN_AGE_LIMITS,
        'filter': request.session.get('fjelltreffen.filter')
    }
    return render(request, 'central/fjelltreffen/index.html', context)
Exemple #3
0
def new(request):
    if not request.user.payment.status['is_paid']:
        return render(request, 'central/fjelltreffen/payment_required.html')

    other_active_annonse_exists = Annonse.get_active().filter(user=request.user, hidden=False).exists()
    context = {
        'counties': County.typical_objects(),
        'annonse_retention_days': settings.FJELLTREFFEN_ANNONSE_RETENTION_DAYS,
        'obscured_age': Annonse.obscure_age(request.user.get_age()),
        'other_active_annonse_exists': other_active_annonse_exists
    }
    return render(request, 'central/fjelltreffen/edit.html', context)
Exemple #4
0
def edit(request, id):
    try:
        annonse = Annonse.objects.get(id=id)
        # checks if the user is the owner
        if annonse.user != request.user:
            raise PermissionDenied
    except Annonse.DoesNotExist:
        return render(request, 'central/fjelltreffen/edit_not_found.html')

    other_active_annonse_exists = Annonse.get_active().exclude(id=annonse.id).filter(user=request.user).exists()
    context = {
        'annonse': annonse,
        'counties': County.typical_objects(),
        'annonse_retention_days': settings.FJELLTREFFEN_ANNONSE_RETENTION_DAYS,
        'obscured_age': Annonse.obscure_age(request.user.get_age()),
        'other_active_annonse_exists': other_active_annonse_exists
    }
    return render(request, 'central/fjelltreffen/edit.html', context)
Exemple #5
0
def index(request):
    county_objects = County.typical_objects().exclude(code='21').order_by('code') # Exclude Svalbard

    # We'll use a "fake" county to represent the entire country, with a sentinel ID value
    fake_national_county = County(
        id='all',
        name='Hele landet',
    )

    # Prepend "entire country" to the county listing
    counties = [fake_national_county]
    counties.extend(county_objects)

    # Split the counties into groups pre-divided for 3 columns
    counties_three_columns = (
        [county for i, county in enumerate(counties) if i % 3 == 0],
        [county for i, county in enumerate(counties) if (i-1) % 3 == 0],
        [county for i, county in enumerate(counties) if (i-2) % 3 == 0],
    )

    full_list = cache.get('foreninger.all.sorted_by_name.with_active_url')
    if full_list is None:
        all_foreninger_by_name = cache.get('foreninger.all.sorted_by_name')
        if all_foreninger_by_name is None:
            all_foreninger_by_name = list(Forening.objects.order_by('name'))
            cache.set('foreninger.all.sorted_by_name', all_foreninger_by_name, 60 * 60 * 24 * 7)

        full_list = [
            (f.name, f.get_active_url() or f.get_main_foreninger()[0].get_active_url())
            for f in all_foreninger_by_name
        ]
        cache.set('foreninger.all.sorted_by_name.with_active_url', full_list, 60 * 60 * 24 * 7)

    context = {
        'categories': Forening.PUBLIC_CATEGORIES,
        'chosen_category': request.GET.get('kategori', 'foreninger').lower(),
        'counties': counties,
        'counties_three_columns': counties_three_columns,
        'chosen_county_name': request.GET.get('fylke', fake_national_county.name),
        'full_list': full_list,
    }
    return render(request, 'central/foreninger/list.html', context)
Exemple #6
0
    def __init__(self, address):
        # Add fields, replacing NULL values with the empty string
        self.field1 = address.a1.strip() if address.a1 is not None else ''
        self.field2 = address.a2.strip() if address.a2 is not None else ''
        self.field3 = address.a3.strip() if address.a3 is not None else ''

        # Set the actual country object
        # Uppercase the country code (just in case - you never know with Focus)
        self.country = FocusCountry.get_by_code(code=address.country_code.upper())

        if self.country.code == 'NO':
            # Norwegians - set the actual zipcode object
            try:
                self.zipcode = Zipcode.get_by_zipcode(zipcode=address.zipcode_id)
            except Zipcode.DoesNotExist:
                # Some addresses have NULL in the zipcode field for some reason.
                # Use a zipcode object with empty fields.
                self.zipcode = Zipcode()

            # Set the actual County object based on the zipcode
            if self.zipcode.zipcode != '':
                county_code = address.zipcode.county_code
                if county_code == INTERNATIONAL_ADDRESS_COUNTY_CODE:
                    # International address; define the county as None for now.
                    self.county = None
                else:
                    self.county = County.get_by_code(code=county_code)
            else:
                self.county = None

        else:
            # Foreigners - ignore zipcode/area
            # Remove country code prefixes
            if self.field1.lower().startswith("%s-" % self.country.code.lower()):
                self.field1 = self.field1[len(self.country.code) + 1:].strip()
            if self.field2.lower().startswith("%s-" % self.country.code.lower()):
                self.field2 = self.field2[len(self.country.code) + 1:].strip()
            if self.field3.lower().startswith("%s-" % self.country.code.lower()):
                self.field3 = self.field3[len(self.country.code) + 1:].strip()
Exemple #7
0
def save(request):
    if request.method != 'POST':
        return redirect('fjelltreffen:mine')

    # If user hasn't paid, allow editing, but not creating new annonser
    if not request.user.payment.status['is_paid'] and request.POST['id'] == '':
        raise PermissionDenied

    # Pre-save validations
    errors = False

    if request.POST.get('id', '') == '':
        # New annonse (not editing an existing one), create it
        annonse = Annonse()
        annonse.user = request.user
    else:
        annonse = Annonse.objects.get(id=request.POST['id'])
        if annonse.user != request.user:
            # someone is trying to edit an annonse that dosent belong to them
            raise PermissionDenied

    if request.POST.get('title', '') == '':
        messages.error(request, 'missing_title')
        errors = True

    if not validator.email(request.POST['email']):
        messages.error(request, 'invalid_email')
        errors = True

    if request.POST.get('text', '') == '':
        messages.error(request, 'missing_text')
        errors = True

    if 'image' in request.FILES:
        try:
            # Uploading image
            file = request.FILES['image']
            data = file.read()
            extension = standardize_extension(file.name.split(".")[-1])

            # Create the thumbnail
            thumb = PIL.Image.open(BytesIO(data)).copy()
            fp = BytesIO()
            thumb.thumbnail(
                [settings.FJELLTREFFEN_IMAGE_THUMB_SIZE, settings.FJELLTREFFEN_IMAGE_THUMB_SIZE],
                PIL.Image.ANTIALIAS,
            )
            thumb.save(fp, extension)
            thumb_data = fp.getvalue()

            # Calculate sha1-hashes
            sha1 = hashlib.sha1()
            sha1.update(data)
            hash = sha1.hexdigest()
            sha1 = hashlib.sha1()
            sha1.update(thumb_data)
            thumb_hash = sha1.hexdigest()
        except Exception:
            logger.warning(
                "Kunne ikke laste opp Fjelltreffen-bilde",
                exc_info=sys.exc_info(),
                extra={'request': request}
            )
            messages.error(request, 'image_upload_error')
            errors = True

    if errors:
        if request.POST.get('id', '') == '':
            return redirect('fjelltreffen:new')
        else:
            return redirect('fjelltreffen:edit', request.POST['id'])

    hidden = request.POST.get('hidden', 'hide') == 'hide'

    # Don't allow showing an already hidden annonse when you haven't paid
    if request.POST['id'] != '':
        if annonse.hidden and not request.user.payment.status['is_paid']:
            hidden = True

    # Don't create new annonser if you already have an active annonse
    if request.POST.get('id', '') == '':
        annonser_to_check = Annonse.get_active()
    else:
        annonser_to_check = Annonse.get_active().exclude(id=request.POST['id'])
    if annonser_to_check.filter(user=request.user).exists():
        hidden = True

    if request.POST.get('county', '') == 'international':
        annonse.county = None
    else:
        annonse.county = County.typical_objects().get(id=request.POST.get('county', ''))
    # TODO: Validate and return form to user with error message
    annonse.title = request.POST.get('title', '')[:255]
    annonse.email = request.POST.get('email', '')[:255]
    if 'image' in request.FILES:
        # Delete any existing image
        annonse.delete_image()

        # Setup AWS connection
        conn = boto.connect_s3(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
        bucket = conn.get_bucket(settings.AWS_S3_BUCKET)

        # Upload the original image to AWS
        key = bucket.new_key("%s/%s.%s" % (settings.AWS_S3_FOLDERS['fjelltreffen'], hash, extension))
        key.content_type = file.content_type
        key.set_contents_from_string(data, policy='public-read')

        # Upload the thumbnail to AWS
        key = bucket.new_key("%s/%s.%s" % (settings.AWS_S3_FOLDERS['fjelltreffen'], thumb_hash, extension))
        key.content_type = file.content_type
        key.set_contents_from_string(thumb_data, policy='public-read')

        # Update the DB fields with new images
        annonse.image = "%s.%s" % (hash, extension)
        annonse.image_thumb = "%s.%s" % (thumb_hash, extension)
    annonse.text = request.POST.get('text', '')
    annonse.hidden = hidden
    annonse.hideage = request.POST.get('hideage', '') == 'hide'
    annonse.save()
    return redirect('fjelltreffen:mine')
Exemple #8
0
def edit(request, aktivitet):
    if request.method == 'GET':
        aktivitet = Aktivitet.objects.prefetch_related('municipalities', 'counties').get(id=aktivitet)
        context = {
            'aktivitet': aktivitet,
            'difficulties': Aktivitet.DIFFICULTY_CHOICES,
            'audiences': AktivitetAudience.AUDIENCE_CHOICES,
            'categories': Aktivitet.CATEGORY_CHOICES,
            'all_foreninger': Forening.get_all_sorted(),
            'cabins': Cabin.objects.order_by('name'),
            'admin_user_search_char_length': settings.ADMIN_USER_SEARCH_CHAR_LENGTH,
            'counties': County.typical_objects().order_by('name'),
            'municipalities': Municipality.objects.order_by('name'),
            'omrader': sorted(Omrade.lookup(), key=lambda o: o.navn),
            'now': datetime.now()
        }
        return render(request, 'common/admin/aktiviteter/edit/edit.html', context)
    elif request.method == 'POST':
        errors = False

        aktivitet = Aktivitet.objects.get(id=aktivitet)

        if aktivitet.is_imported():
            # Should only be possible by circumventing client-side restrictions
            return redirect('admin.aktiviteter.views.edit', aktivitet.id)

        if 'code' in request.POST:
            aktivitet.code = request.POST['code']

        if 'title' in request.POST:
            aktivitet.title = request.POST['title']

        if 'description' in request.POST:
            aktivitet.description = request.POST['description']

        if 'difficulty' in request.POST:
            aktivitet.difficulty = request.POST['difficulty']

        if 'audiences' in request.POST:
            aktivitet.audiences = [
                AktivitetAudience.objects.get(name=audience)
                for audience in request.POST.getlist('audiences')
            ]

        if 'category' in request.POST:
            aktivitet.category = request.POST['category']

        if 'category_type' in request.POST:
            aktivitet.category_type = request.POST['category_type']

        if 'publish' in request.POST:
            aktivitet.published = request.POST.get('publish') == 'publish'

        if 'getting_there' in request.POST:
            aktivitet.getting_there = request.POST['getting_there']

        if 'omrader' in request.POST:
            aktivitet.omrader = request.POST.getlist('omrader')

        if 'ntb_id' not in request.POST or request.POST['ntb_id'] == '':
            aktivitet.turforslag = None
        else:
            aktivitet.turforslag = request.POST['ntb_id']

        if aktivitet.published:
            # If published, set the extra relevant fields (otherwise ignore them)
            aktivitet.private = request.POST['private'] == 'private'
            try:
                aktivitet.pub_date = datetime.strptime(request.POST['pub_date'], "%d.%m.%Y").date()
            except ValueError:
                errors = True
                messages.error(request, 'invalid_date_format')

        forening_type, forening_id = request.POST['forening'].split(':')
        if forening_type == 'forening':
            forening = Forening.objects.get(id=forening_id)
            if not forening in request.user.children_foreninger():
                raise PermissionDenied
            aktivitet.forening = forening
        elif forening_type == 'cabin':
            aktivitet.forening_cabin = Cabin.objects.get(id=forening_id)
        else:
            raise PermissionDenied

        if 'co_foreninger[]' in request.POST and request.POST['co_foreninger[]'] != '':
            co_foreninger = []
            co_foreninger_cabin = []
            for co_forening in request.POST.getlist('co_foreninger[]'):
                type, id = co_forening.split(':')
                if type == 'forening':
                    co_foreninger.append(id)
                elif type == 'cabin':
                    co_foreninger_cabin.append(id)
                else:
                    raise PermissionDenied

            aktivitet.co_foreninger = co_foreninger
            aktivitet.co_foreninger_cabin = co_foreninger_cabin
        else:
            aktivitet.co_foreninger = []
            aktivitet.co_foreninger_cabin = []

        if 'latlng' in request.POST:
            latlng = request.POST['latlng'].split(',')
            if len(latlng) == 2:
                aktivitet.start_point = Point(float(latlng[0]), float(latlng[1]))

        aktivitet.save()

        aktivitet.counties = request.POST.getlist('counties')
        aktivitet.municipalities = request.POST.getlist('municipalities')

        aktivitet.category_tags.clear()
        if 'category_tags' in request.POST and request.POST['category_tags'] != '':
            for tag in request.POST.getlist('category_tags'):
                obj, created = Tag.objects.get_or_create(name=tag)
                aktivitet.category_tags.add(obj)

        aktivitet.images.all().delete()
        for i, image in parse_html_array(request.POST, 'images').items():
            AktivitetImage(
                aktivitet=aktivitet,
                url=image['url'],
                text=image['description'],
                photographer=image['photographer'],
                order=i
            ).save()

        dates = parse_html_array(request.POST, 'dates').items()

        # Remove the date objects that were explicitly deleted (checks and verifications are done
        # client-side). Verify that those that would be implicitly deleted (by not being POSTed for
        # editing) match those explicitly POSTed.
        date_ids = [int(d['id']) for k, d in dates if d['id'] != '']
        implicit_del = set([date.id for date in aktivitet.dates.all() if date.id not in date_ids])

        if len(implicit_del) > 0:
            # Better to raise an exception and not delete anything. The user will be confused and
            # lose edits, but we'll get a report and hopefully be able to fix this, if it ever
            # happens.
            raise Exception("Implicit delete of AktivitetDate is strictly forbidden!")

        for i, date in dates:
            if date['id'] != '':
                # @TODO Check if this can be exploited. Can you hijack another trip's date by
                # setting an arbitrary ID in the date['id'] field?
                model = AktivitetDate.objects.get(id=date['id'])
            else:
                model = AktivitetDate(aktivitet=aktivitet)

            # @TODO for existing dates; if model.start_date > now; dissalow editing.

            # Explicit delete of dates
            if date['status'] == 'delete':
                if date['id'] != '':
                    if model.participant_count() > 0:
                        raise Exception("Date with participants can not be deleted!")
                    model.delete()
                continue

            try:
                if not date['start_time']: date['start_time'] = '08:00'
                if not date['end_time']: date['end_time'] = '16:00'

                # @TODO check start_time > now
                model.start_date = datetime.strptime(
                    "%s %s" % (date['start_date'], date['start_time']),
                    "%d.%m.%Y %H:%M"
                )

                # @TODO check end_time > start_time
                model.end_date = datetime.strptime(
                    "%s %s" % (date['end_date'], date['end_time']),
                    "%d.%m.%Y %H:%M"
                )

                # @TODO check start_date > meeting_time
                if date['start_date'] and date['meeting_time']:
                    model.meeting_time = datetime.strptime(
                        "%s %s" % (date['start_date'], date['meeting_time']),
                        "%d.%m.%Y %H:%M"
                    )

                if not date['signup_method'] or date['signup_method'] == 'none':
                    # To the next maintainer. This block indicates that a date does not allow
                    # signup. However, keep in mind that this might be an existing date with
                    # participants. Hence, do not set model.participant to None event though it
                    # might be tempting!

                    model.signup_enabled = False
                    model.signup_start = None
                    model.signup_deadline = None
                    model.cancel_deadline = None

                elif date['signup_method'] == 'normal' or date['signup_method'] == 'simple':
                    model.signup_enabled = True

                    if date.get('max_participants_limited'):
                        model.max_participants = date['max_participants']
                    else:
                        model.max_participants = None

                    if date.get('no_signup_start') == '1':
                        model.signup_start = None
                    else:
                        model.signup_start = datetime.strptime(
                            date['signup_start'],
                            "%d.%m.%Y",
                        ).date()

                    if 'no_signup_deadline' in date and date['no_signup_deadline'] == '1':
                        model.signup_deadline = None
                    elif 'signup_deadline' in date and date['signup_deadline'] != '':
                        model.signup_deadline = datetime.strptime(
                            date['signup_deadline'],
                            "%d.%m.%Y",
                        ).date()

                    if 'no_cancel_deadline' in date and date['no_cancel_deadline'] == '1':
                        model.cancel_deadline = None
                    elif 'cancel_deadline' in date and date['cancel_deadline'] != '':
                        model.cancel_deadline = datetime.strptime(
                            date['cancel_deadline'], "%d.%m.%Y"
                        ).date()

                else:
                    raise Exception("Unrecognized POST value for signup_method field")

            except ValueError:
                errors = True
                messages.error(request, 'invalid_date_format')
                return redirect('admin.aktiviteter.views.edit', aktivitet.id)

            # Note that simple signup is currently disabled and due to be removed
            model.signup_simple_allowed = False
            model.meeting_place = date['meeting_place']
            model.contact_type = date['contact_type']
            model.contact_custom_name = date['contact_custom_name']
            model.contact_custom_phone = date['contact_custom_phone']
            model.contact_custom_email = date['contact_custom_email']
            model.should_have_turleder = date.get('should_have_turleder') == '1'
            model.save()

            if date.get('should_have_turleder') == '1':
                # We need to specify the key for this particular field because the parse_html_array
                # function does not properly parse multidimensional arrays.
                key = 'dates[%s][turleder][]' % i
                if key in request.POST and request.POST[key] != '':
                    model.turledere = request.POST.getlist(key)
            else:
                model.turledere = []

        if not errors:
            messages.info(request, 'save_success')

        if json.loads(request.POST['preview']):
            return redirect('admin.aktiviteter.views.preview', aktivitet.id)
        else:
            return redirect('admin.aktiviteter.views.edit', aktivitet.id)