def get_queryset(self):
        today = date.today()
        queryset = AktivitetDate.get_searchable().filter(
            start_date__gte=today
        ).select_related(
            'aktivitet',
            'aktivitet__organizer_forening',
        ).prefetch_related(
            'participant_groups',
            'participant_groups__participants',
            'sherpa2_participants',

            'aktivitet__counties',
            'aktivitet__municipalities',
            'aktivitet__co_organizers_forening',
            'aktivitet__organizer_forening__sites',
            'aktivitet__images',
            'aktivitet__category_tags',
        ).distinct()

        return queryset.all()
示例#2
0
    def parse(self, widget_options, site):
        aktivitet_dates = AktivitetDate.get_published().filter(
            Q(aktivitet__forening__in=widget_options['foreninger']) |
            Q(aktivitet__co_foreninger__in=widget_options['foreninger']),
            aktivitet__private=False,
            start_date__gte=date.today(),
        )

        url_query_parameters = []
        limit = widget_options.get('limit', 50)
        total = aktivitet_dates.count()
        more_activities_count = total - limit

        # Skip if none, or all, audiences were chosen
        if len(widget_options['audiences']) > 0 and len(widget_options['audiences']) < len(AktivitetAudience.AUDIENCE_CHOICES):
            aktivitet_dates = aktivitet_dates.filter(aktivitet__audiences__name__in=widget_options['audiences'])
            url_query_parameters.append("audiences=%s" % ",".join(widget_options['audiences']))

        # Skip if none, or all, categories were chosen
        if len(widget_options['categories']) > 0 and len(widget_options['categories']) < len(Aktivitet.CATEGORY_CHOICES):
            aktivitet_dates = aktivitet_dates.filter(
                aktivitet__category__in=widget_options['categories'],
            )
            url_query_parameters.append("categories=%s" % ",".join(widget_options['categories']))

        if len(widget_options['foreninger']) > 0:
            organizers = ["forening:%s" % f for f in widget_options['foreninger']]
            url_query_parameters.append("organizers=%s" % ",".join(organizers))

        aktivitet_dates = aktivitet_dates.order_by('start_date')[:limit]
        see_more_query_params = "&".join(url_query_parameters)

        return {
            'aktivitet_dates': aktivitet_dates,
            'see_more_query_params': see_more_query_params,
            'total': total,
            'limit': limit,
            'more_activities_count': more_activities_count
        }
示例#3
0
def filter_aktivitet_dates(filter, user, active_forening, requested_forening):
    """
    Filters AktivitetDates based on:
    - The provided query parameters
    - The current user and their permissions
    - The currently active forening (note that this differs from the requested forening. Forening-admins may request
      aktivitetdates for a child-forening)
    Returns AktivitetDate objects.
    """
    if filter.get('kladd') == 'false':
        dates = AktivitetDate.get_searchable()
    else:
        dates = AktivitetDate.objects

    dates = dates.select_related(
        'aktivitet',
        'aktivitet__organizer_forening',
    ).prefetch_related(
        'participant_groups',
        'participant_groups__participants',
        'sherpa2_participants',
    )

    if filter.get('sok'):
        dates = dates.filter(
            Q(aktivitet__title__icontains=filter.get('sok')) |
            Q(aktivitet__code=filter.get('sok'))
        )

    today = date.today()
    if filter.get('tid') in ['denne_uke', 'neste_uke', 'neste_maned']:
        if filter.get('tid') == 'denne_uke':
            start = today - timedelta(days=today.weekday())
            end = today + timedelta(days=-start.weekday(), weeks=1)

        elif filter.get('tid') == 'neste_uke':
            start = today + timedelta(days=-today.weekday(), weeks=1)
            end = today + timedelta(days=-today.weekday(), weeks=2)

        else:
            (start_year, start_month) = divmod(today.month, 12)
            (end_year, end_month) = divmod(today.month + 1, 12)

            start = today.replace(year=today.year + start_year, month=start_month + 1, day=1)
            end = today.replace(year=today.year + end_year, month=end_month + 1, day=1)

        dates = dates.filter(start_date__gte=start, start_date__lt=end)
    elif filter.get('tid') != 'alle':
        dates = dates.filter(start_date__gte=today)

    dates = dates.order_by('start_date').distinct()

    # If the user is admin, include dates organized by the children of the active forening
    if user.is_admin_in_forening(active_forening):
        dates = dates.filter(
            Q(aktivitet__organizer_forening=requested_forening) |
            Q(aktivitet__co_organizers_forening=requested_forening) |
            Q(
                aktivitet__organizer_forening__parents=requested_forening,
                aktivitet__organizer_forening__type='turgruppe',
            ) |
            Q(
                aktivitet__co_organizers_forening__parents=requested_forening,
                aktivitet__co_organizers_forening__type='turgruppe',
            )
        )
    else:
        dates = dates.filter(
            Q(aktivitet__organizer_forening=requested_forening) |
            Q(aktivitet__co_organizers_forening=requested_forening)
        )
    return dates
示例#4
0
文件: util.py 项目: simensma/sherpa
def filter_aktivitet_dates(filter):

    # To the next mainainer: The filter param is a mutateable query dict such that this util method
    # can split strings into lists which the template logic is dependent upon. If you find a better
    # way, please refactor this code.

    dates = AktivitetDate.get_published().select_related(
        'aktivitet__forening',
    ).prefetch_related(
        'aktivitet',
        'aktivitet__images',
        'aktivitet__forening__sites',
        'aktivitet__co_foreninger',
    ).filter(aktivitet__private=False)

    if filter.get('search', '') and len(filter['search'].strip()) > 2:
        words = filter['search'].split()

        dates = dates.filter(
            Q(reduce(lambda x, y: x & y, [Q(aktivitet__title__icontains=word) | Q(aktivitet__description__icontains=word) for word in words])) |
            Q(aktivitet__code=filter['search'])
        )

    if filter.get('omrader', ''):
        filter['omrader'] = filter['omrader'].split(',')

        for omrade in filter['omrader']:
            dates = dates.extra(
                where=['%s = ANY ("{0}"."omrader")'.format(Aktivitet._meta.db_table)],
                params=[omrade],
            )

    if filter.get('categories', ''):
        filter['categories'] = filter['categories'].split(',')

        dates = dates.filter(aktivitet__category__in=filter['categories'])

    if filter.get('category_types', ''):
        filter['category_types'] = filter['category_types'].split(',')

        # Note that we're checking for both types and tags, and since objects may have the same tag specified twice,
        # it'll require an explicit distinct clause in our query
        dates = dates.filter(
            Q(aktivitet__category_type__in=filter['category_types']) |
            Q(aktivitet__category_tags__name__in=filter['category_types'])
        )

    if filter.get('audiences', ''):
        filter['audiences'] = filter['audiences'].split(',')

        dates = dates.filter(aktivitet__audiences__name__in=filter['audiences'])

    if filter.get('difficulties', ''):
        filter['difficulties'] = filter['difficulties'].split(',')

        dates = dates.filter(aktivitet__difficulty__in=filter['difficulties'])

    if filter.get('lat_lng', '') and len(filter['lat_lng'].split(',')) == 2:
        filter['lat_lng'] = filter['lat_lng'].split(',')

        # Rule of thumb for buffer; 1 degree is about 100 km
        boundary = geos.Point(float(filter['lat_lng'][0]), float(filter['lat_lng'][1])).buffer(0.5)

        dates = dates.filter(aktivitet__start_point__within=boundary)

    # @TODO refactor to make use of django range query
    # https://docs.djangoproject.com/en/dev/ref/models/querysets/#range
    try:
        if filter.get('start_date', ''):
            dates = dates.filter(start_date__gte=datetime.strptime(filter['start_date'], "%d.%m.%Y"))
        else:
            today = date.today()
            dates = dates.filter(start_date__gte=datetime(today.year, today.month, today.day))

        if filter.get('end_date'):
            dates = dates.filter(end_date__lte=datetime.strptime(filter['end_date'], "%d.%m.%Y"))
    except (ValueError, KeyError):
        pass

    if filter.get('organizers', ''):
        filter['organizers'] = filter['organizers'].split(',')

        filter['foreninger'] = []
        filter['cabins'] = []

        for organizer in filter['organizers']:
            try:
                type, id = organizer.split(':')
                if type == 'forening':
                    filter['foreninger'].append(int(id))
                elif type == 'cabin':
                    filter['cabins'].append(int(id))
            except ValueError:
                continue

        if filter['foreninger']:
            dates = dates.filter(
                Q(aktivitet__forening__in=filter['foreninger']) |
                Q(aktivitet__co_foreninger__in=filter['foreninger'])
            )

        if filter['cabins']:
            dates = dates.filter(
                Q(aktivitet__forening_cabin__in=filter['cabins']) |
                Q(aktivitet__co_foreninger_cabin__in=filter['cabins'])
            )

    dates = dates.distinct().order_by(
        'start_date'
    )

    return filter, dates
示例#5
0
def filter_aktivitet_dates(filter):

    # To the next mainainer: The filter param is a mutateable query dict such that this util method
    # can split strings into lists which the template logic is dependent upon. If you find a better
    # way, please refactor this code.

    dates = AktivitetDate.get_searchable().select_related(
        'aktivitet',
        'aktivitet__organizer_forening',
    ).prefetch_related(
        'aktivitet__images',
        'aktivitet__organizer_forening__sites',
        'aktivitet__co_organizers_forening',
        'aktivitet__category_tags',
    )

    if filter.get('search', '') and len(filter['search'].strip()) > 2:
        words = filter['search'].split()

        dates = dates.filter(
            Q(reduce(lambda x, y: x & y, [
                Q(aktivitet__title__icontains=word)
                | Q(aktivitet__description__icontains=word)
                | Q(aktivitet__title_en__icontains=word)
                | Q(aktivitet__description_en__icontains=word)
                for word in words
            ]))
            | Q(aktivitet__code=filter['search'])
        )

    if filter.get('omrader', ''):
        filter['omrader'] = filter['omrader'].split(',')

        # Build the where clause to search all omrader for each filtered omrade
        # Use a list with the ANY construct repeated for each filtered omrade, and join them with OR
        constructs = ['%s = ANY ("omrader")'] * len(filter['omrader'])
        where_clause = ' OR '.join(constructs)
        dates = dates.extra(
            where=[where_clause],
            params=filter['omrader'],
        )

    if filter.get('categories', ''):
        filter['categories'] = filter['categories'].split(',')

        dates = dates.filter(aktivitet__category__in=filter['categories'])

    if filter.get('category_types', ''):
        filter['category_types'] = filter['category_types'].split(',')

        # Note that we're checking for both types and tags, and since objects may have the same tag specified twice,
        # it'll require an explicit distinct clause in our query
        dates = dates.filter(
            Q(aktivitet__category_type__in=filter['category_types']) |
            Q(aktivitet__category_tags__name__in=filter['category_types'])
        )

    # Note that the UI doesn't expose a control for the category_tags filter, but it can be used in widgets, which in
    # turn links to the full search with the same query parameters.
    if filter.get('category_tags', ''):
        filter['category_tags'] = filter['category_tags'].split(',')
        dates = dates.filter(
            aktivitet__category_tags__name__in=filter['category_tags'],
        )

    if filter.get('audiences', ''):
        filter['audiences'] = filter['audiences'].split(',')

        # Note the usage of 'overlap' here to combine multiple audiences by 'or'
        dates = dates.filter(aktivitet__audiences__overlap=filter['audiences'])

    if filter.get('difficulties', ''):
        filter['difficulties'] = filter['difficulties'].split(',')

        dates = dates.filter(aktivitet__difficulty__in=filter['difficulties'])

    try:
        if filter.get('lat_lng', '') and len(filter['lat_lng'].split(',')) == 2:
            filter['lat_lng'] = filter['lat_lng'].split(',')

            # Rule of thumb for buffer; 1 degree is about 100 km
            boundary = geos.Point(float(filter['lat_lng'][0]), float(filter['lat_lng'][1])).buffer(0.5)

            dates = dates.filter(aktivitet__start_point__within=boundary)
    except ValueError:
        pass

    # @TODO refactor to make use of django range query
    # https://docs.djangoproject.com/en/dev/ref/models/querysets/#range
    try:
        if filter.get('start_date', ''):
            dates = dates.filter(start_date__gte=datetime.strptime(filter['start_date'], "%d.%m.%Y").date())
        else:
            dates = dates.filter(start_date__gte=date.today())

        if filter.get('end_date'):
            dates = dates.filter(end_date__lte=datetime.strptime(filter['end_date'], "%d.%m.%Y").date())
    except (ValueError, KeyError):
        pass

    if filter.get('min_duration'):
        try:
            dates = dates.filter(duration_days__gte=filter['min_duration'])
        except ValueError:
            pass

    if filter.get('max_duration'):
        try:
            dates = dates.filter(duration_days__lte=filter['max_duration'])
        except ValueError:
            pass

    if filter.get('organizers', ''):
        filter['organizers'] = filter['organizers'].split(',')

        filter['foreninger'] = []
        filter['cabins'] = []

        for organizer in filter['organizers']:
            try:
                type, id = organizer.split(':')
                if type == 'forening':
                    filter['foreninger'].append(int(id))
                elif type == 'cabin':
                    filter['cabins'].append(id)
            except ValueError:
                continue

        if filter['foreninger'] or filter['cabins']:
            dates = dates.filter(
                Q(aktivitet__organizer_forening__in=filter['foreninger']) |
                Q(aktivitet__co_organizers_forening__in=filter['foreninger']) |
                Q(aktivitet__organizer_cabin__in=filter['cabins']) |
                Q(aktivitet__co_organizers_cabin__overlap=filter['cabins'])
            )

    dates = dates.distinct()

    return filter, dates
示例#6
0
文件: views.py 项目: simensma/sherpa
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)
示例#7
0
def index(request):
    turledere = cache.get('admin.turleder_count')
    if turledere is None:
        turledere = Turleder.objects.only(
            # Select only the related approved forening, and only the ID from that model
            'forening_approved',
            'forening_approved__id',
        ).select_related(
            # Join the related forening into this query as we'll traverse that later
            'forening_approved',
        ).distinct(
            # The Turleder model may have >1 references to a user, so select distinctly on user
            'user',
        )

        # Make sure the lazy queryset has been evaluated before caching it
        len(turledere)

        cache.set('admin.turleder_count', turledere, 60 * 60 * 24 * 14)

    turleder_stats = {
        'total': len(turledere),
        # Filter on the local forening in code - it's prefetched, so that's much faster, and it lets us cache the
        # entire query instead of having a seperate cache key per forening
        'local': len([t for t in turledere if t.forening_approved == request.active_forening]),
    }

    aktiviteter = cache.get('admin.aktivitet_count.%s' % request.active_forening.id)
    if aktiviteter is None:
        aktiviteter = AktivitetDate.get_searchable().filter(
            Q(aktivitet__organizer_forening=request.active_forening) |
            Q(aktivitet__co_organizers_forening=request.active_forening),
            start_date__gte=date.today(),
        ).count()
        cache.set('admin.aktivitet_count', aktiviteter, 60 * 60 * 6)

    dashboard_stats = {
        'turledere': turleder_stats,
        'aktiviteter': aktiviteter,
    }

    betablog = cache.get('admin.betablog')
    BETABLOG_ITEM_COUNT = 4
    if betablog is None:
        try:
            betablog = []
            librato.increment('sherpa.requests.betablog')
            r = requests.get("http://beta.dnt.no/", params={'feed': 'rss2'})
            channel = ET.fromstring(r.content).find('channel')
            for item in channel.findall('item')[:BETABLOG_ITEM_COUNT]:
                content = item.find('description').text
                image = None
                m = re.search('<img.*?src="(.*?)" ', content)
                if m is not None:
                    image = m.group(1)
                pub_date = datetime.strptime(item.find('pubDate').text[:-6], "%a, %d %b %Y %H:%M:%S")

                betablog.append({
                    'title': item.find('title').text,
                    'link': item.find('link').text,
                    'content': content,
                    'image': image,
                    'pub_date': pub_date,
                    'is_new': pub_date > datetime.now() - timedelta(days=7),
                })
        except:
            logger.warning(
                "Kunne ikke hente innhold fra betabloggen",
                exc_info=sys.exc_info(),
                extra={'request': request}
            )

        cache.set('admin.betablog', betablog, 60 * 60 * 12)

    context = {
        'betablog': betablog,
        'dashboard_stats': dashboard_stats,
    }
    return render(request, 'central/admin/dashboard.html', context)
示例#8
0
def index(request):
    turleder_stats = cache.get('admin.turleder_count')
    if turleder_stats is None:
        turledere = Turleder.objects.only(
            # Select only the related approved forening, and only the ID from that model
            'forening_approved',
            'forening_approved__id',
        ).select_related(
            # Join the related forening into this query as we'll traverse that later
            'forening_approved',
        ).distinct(
            # The Turleder model may have >1 references to a user, so select distinctly on user
            'user',
        )

        turleder_stats = {
            'total': len(turledere),
            'all': {
                f.id: len([t for t in turledere if t.forening_approved == f])
                for f in Forening.objects.only('id')
            },
        }
        cache.set('admin.turleder_count', turleder_stats, 60 * 60 * 24 * 14)

    # Set a shortcut key for the count for the current active forening, outside of cache logic
    turleder_stats['active_forening'] = turleder_stats['all'].get(request.active_forening.id, 0)

    aktiviteter = cache.get('admin.aktivitet_count.%s' % request.active_forening.id)
    if aktiviteter is None:
        aktiviteter = AktivitetDate.get_searchable().filter(
            Q(aktivitet__organizer_forening=request.active_forening) |
            Q(aktivitet__co_organizers_forening=request.active_forening),
            start_date__gte=date.today(),
        ).count()
        cache.set('admin.aktivitet_count.%s' % request.active_forening.id, aktiviteter, 60 * 60 * 6)

    dashboard_stats = {
        'turledere': turleder_stats,
        'aktiviteter': aktiviteter,
    }

    # Get info on user announcements
    active_count = UserAnnouncement.objects.filter(
        # Set to be published before now()
        Q(pub_date__isnull=True) |
        Q(pub_date__lte=datetime.now()),

        # Set to be unpublished after now()
        Q(unpub_date__isnull=True) |
        Q(unpub_date__gt=datetime.now()),
    ).count()

    upcoming_count = UserAnnouncement.objects.filter(
        # Set to be unpublished after now()
        Q(unpub_date__isnull=True) |
        Q(unpub_date__gt=datetime.now()),

        # Set to be unpublished before now()
        pub_date__gt=datetime.now(),
    ).count()

    context = {
        'user_announcements_active_count': active_count,
        'user_announcements_upcoming_count': upcoming_count,
        'dashboard_stats': dashboard_stats,
    }
    return render(request, 'central/admin/dashboard.html', context)
    def parse(self, widget_options, site, preview_context):
        aktivitet_dates = AktivitetDate.get_searchable().filter(
            start_date__gte=date.today(),
        ).select_related(
            'aktivitet',
            'aktivitet__organizer_forening',
        ).prefetch_related(
            'aktivitet__images',
            'aktivitet__co_organizers_forening',
        )

        #
        # Note that all widget search filters should match the behavior in the standard search view. Not only for
        # consistency's sake, but also because we'll want to link from the widget to the full search with the same
        # search parameters repeated; expecting the full search to display the exact same results.
        #

        url_query_parameters = {}

        # Apply audience filters, if any
        if len(widget_options['audiences']) > 0:
            # Note the usage of 'overlap' here to combine multiple audiences by 'or'
            aktivitet_dates = aktivitet_dates.filter(aktivitet__audiences__overlap=widget_options['audiences'])
            url_query_parameters['audiences'] = ",".join(widget_options['audiences'])

        # Apply category filters, if any
        if len(widget_options['categories']) > 0:
            aktivitet_dates = aktivitet_dates.filter(
                aktivitet__category__in=widget_options['categories'],
            )
            url_query_parameters['categories'] = ",".join(widget_options['categories'])

        # Apply category type filters, if any
        if len(widget_options['category_types']) > 0:
            # Note that we're checking for both types and tags, and since objects may have the same tag specified twice,
            # it'll require an explicit distinct clause in our query
            aktivitet_dates = aktivitet_dates.filter(
                Q(aktivitet__category_type__in=widget_options['category_types']) |
                Q(aktivitet__category_tags__name__in=widget_options['category_types'])
            )
            url_query_parameters['category_types'] = ",".join(widget_options['category_types'])

        # Apply category tag filters, if any
        if len(widget_options['category_tags']) > 0:
            aktivitet_dates = aktivitet_dates.filter(
                aktivitet__category_tags__name__in=widget_options['category_tags'],
            )

            # Note that the full search UI doesn't expose a control for this parameter, so the initial page load will
            # work, but when one changes any other filter, the category_tags filter will be cleared, which is suboptimal
            url_query_parameters['category_tags'] = ",".join(widget_options['category_tags'])

        # Apply organizer filter, if any
        if len(widget_options['organizers']) > 0:
            foreninger = []
            cabins = []

            for organizer in widget_options['organizers']:
                type, id = organizer.split(':')
                if type == 'forening':
                    foreninger.append(id)
                elif type == 'cabin':
                    cabins.append(id)

            # This will always be true (since we checked organizers length above), but just to be explicit: The filter
            # should not be executed if both lists are empty.
            if len(foreninger) > 0 or len(cabins) > 0:
                aktivitet_dates = aktivitet_dates.filter(
                    Q(aktivitet__organizer_forening__in=foreninger) |
                    Q(aktivitet__co_organizers_forening__in=foreninger) |
                    Q(aktivitet__organizer_cabin__in=cabins) |
                    Q(aktivitet__co_organizers_cabin__overlap=cabins)
                )

            url_query_parameters['organizers'] = ",".join(widget_options['organizers'])

        limit = widget_options.get('limit', 50)
        aktivitet_dates = aktivitet_dates.distinct()
        total = aktivitet_dates.count()
        more_activities_count = total - limit

        aktivitet_dates = aktivitet_dates.order_by('start_date')[:limit]
        see_more_query_params = "&".join([
            "%s=%s" % (urlencode(key), urlencode(value))
            for key, value in url_query_parameters.items()
        ])

        show_images = widget_options.get('show_images', False)

        return {
            'aktivitet_dates': aktivitet_dates,
            'see_more_query_params': see_more_query_params,
            'total': total,
            'limit': limit,
            'more_activities_count': more_activities_count,
            'show_images': show_images,
        }