Example #1
0
class ProductVersionView(ListView):
    template_name = 'security/product-advisories.html'
    context_object_name = 'product_versions'
    allow_empty = False

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(ProductVersionView, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        slug = u'{product}-{version}'.format(**self.kwargs)
        qfilter = Q(slug__startswith=slug + '.')
        dots = slug.count('.')
        if dots < 2:
            # add exact match if not point release
            if slug.endswith('.0'):
                # stip trailing .0 as products are stored without them
                slug = slug[:-2]
            qfilter |= Q(slug__exact=slug)
        versions = Product.objects.filter(qfilter)
        return sorted(versions, reverse=True)

    def get_context_data(self, **kwargs):
        cxt = super(ProductVersionView, self).get_context_data(**kwargs)
        prod_name, version = self.kwargs['product'], self.kwargs['version']
        cxt['is_obsolete'] = product_is_obsolete(prod_name, version)
        cxt['product_name'] = '{0} {1}'.format(cxt['product_versions'][0].product, version)
        cxt['product_slug'] = prod_name
        return cxt
Example #2
0
class VolumePageList(ListView, VaryOnCookieMixin):
    '''Display a paginated list of :class:`~readux.books.models.Page`
    objects associated with a single :class:`~readux.books.models.Volume`.
    Pages are displayed by thumbnail; thumbnails include an annotation count
    indicator for logged in users with annotations.
    '''

    template_name = 'books/volume_pages_list.html'
    paginate_by = 30
    context_object_name = 'pages'

    @method_decorator(last_modified(view_helpers.volume_pages_modified))
    def dispatch(self, *args, **kwargs):
        return super(VolumePageList, self).dispatch(*args, **kwargs)

    def get_queryset(self):
        self.repo = Repository(request=self.request)
        # store the volume for use in get_context_data
        self.vol = self.repo.get_object(self.kwargs['pid'], type=Volume)
        if not self.vol.exists or not self.vol.is_a_volume:
            raise Http404
        return self.vol.find_solr_pages()

    def get_context_data(self, **kwargs):
        context_data = super(VolumePageList, self).get_context_data()

        context_data.update({
            'vol': self.vol,
            'form': BookSearch(),  # form for searching in this book
        })

        # if user is authenticated, check for annotations on this volume
        if self.request.user.is_authenticated():
            notes = self.vol.page_annotation_count(self.request.user)
            # method returns a dict for easy lookup;
            # strip out base site url for easy lookup in the template
            # (need leading / left to match item urls)
            domain = get_current_site(self.request).domain.rstrip('/')
            if not domain.startswith('https'):
                domain = 'https://' + domain

            annotated_pages = dict([(k.replace(domain, ''), v)
                                    for k, v in notes.iteritems()])
        else:
            annotated_pages = {}
        context_data.update({
            'annotated_pages': annotated_pages,
            'annotation_search_enabled': bool(annotated_pages)
        })

        # Check if the first page of the volume is wider than it is tall
        # to set the layout of the pages
        first_page = self.vol.pages[0]
        if first_page.width > first_page.height:
            layout = 'landscape'
        else:
            layout = 'default'
        context_data['layout'] = layout

        return context_data
Example #3
0
class ProductView(ListView):
    template_name = 'security/product-advisories.html'
    context_object_name = 'product_versions'
    allow_empty = False
    minimum_versions = {
        'firefox': Version('4.0'),
        'thunderbird': Version('6.0'),
        'seamonkey': Version('2.3'),
    }

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(ProductView, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        product_slug = self.kwargs.get('slug')
        versions = Product.objects.filter(product_slug=product_slug)
        min_version = self.minimum_versions.get(product_slug)
        if min_version:
            versions = [vers for vers in versions if vers.version >= min_version]
        return sorted(versions, reverse=True)

    def get_context_data(self, **kwargs):
        cxt = super(ProductView, self).get_context_data(**kwargs)
        cxt['product_name'] = cxt['product_versions'][0].product
        return cxt
Example #4
0
class AdvisoriesView(ListView):
    template_name = 'security/advisories.html'
    queryset = SecurityAdvisory.objects.only('id', 'impact', 'title', 'announced')
    context_object_name = 'advisories'

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(AdvisoriesView, self).dispatch(request, *args, **kwargs)
Example #5
0
class AdvisoryView(DetailView):
    model = SecurityAdvisory
    template_name = 'security/advisory.html'
    context_object_name = 'advisory'

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(AdvisoryView, self).dispatch(request, *args, **kwargs)
Example #6
0
    def as_view(cls, **initkwargs):
        def normalize_key_prefix(key_prefix):
            def _key_prefix(request, *args, **kwargs):
                return str(
                    key_prefix(request, *args, **kwargs)
                ).replace(' ', '_')
            return _key_prefix

        patched_view = view = super().as_view(**initkwargs)

        patched_view = http.etag(cls.etag)(patched_view)
        patched_view = http.last_modified(cls.last_modified)(patched_view)
        patched_view = cache_page(
            cache_timeout=cls._expires,
            key_prefix=normalize_key_prefix(cls.last_modified),
        )(patched_view)

        view = decorators.replace_if(
            lambda request, *args, **kwargs: request.method in ('GET', 'HEAD'),
            replacement=patched_view,
        )(view)

        @functools.wraps(cls.as_view)
        def logging_view(request, *args, **kwargs):

            request_logger.debug(
                'request_method: %(request_method)s, '
                'request_path: %(request_path)s, '
                'request_headers: %(request_headers)s, '
                'request_params: %(request_params)s, '
                'request_data: %(request_data)s, ',
                dict(
                    request_method=request.method,
                    request_path=request.path,
                    request_headers=request.META,
                    request_params=request.GET,
                    request_data=request.POST,
                ),
            )

            response = view(request, *args, **kwargs)

            response_logger.debug(
                'response_code: %(response_code)s, '
                'response_headers: %(response_headers)s, '
                'response_data: %(response_data)s',
                dict(
                    response_code=response.status_code,
                    response_headers=response.items(),
                    response_data=response.content,
                ),
            )

            return response

        return logging_view
Example #7
0
    def as_view(cls, **initkwargs):
        def normalize_key_prefix(key_prefix):
            def _key_prefix(request, *args, **kwargs):
                return str(
                    key_prefix(request, *args, **kwargs)
                ).replace(' ', '_')
            return _key_prefix

        patched_view = view = super().as_view(**initkwargs)

        patched_view = http.etag(cls.etag)(patched_view)
        patched_view = http.last_modified(cls.last_modified)(patched_view)
        patched_view = cache_page(
            cache_timeout=cls._expires,
            key_prefix=normalize_key_prefix(cls.last_modified),
        )(patched_view)

        view = decorators.replace_if(
            lambda request, *args, **kwargs: request.method in ('GET', 'HEAD'),
            replacement=patched_view,
        )(view)

        @functools.wraps(cls.as_view)
        def logging_view(request, *args, **kwargs):

            request_logger.debug(
                'request_method: %(request_method)s, '
                'request_path: %(request_path)s, '
                'request_headers: %(request_headers)s, '
                'request_params: %(request_params)s, '
                'request_data: %(request_data)s, ',
                dict(
                    request_method=request.method,
                    request_path=request.path,
                    request_headers=request.META,
                    request_params=request.GET,
                    request_data=request.POST,
                ),
            )

            response = view(request, *args, **kwargs)

            response_logger.debug(
                'response_code: %(response_code)s, '
                'response_headers: %(response_headers)s, '
                'response_data: %(response_data)s',
                dict(
                    response_code=response.status_code,
                    response_headers=response.items(),
                    response_data=response.content,
                ),
            )

            return response

        return logging_view
Example #8
0
class CollectionList(ListView):
    '''List and display all collections'''
    model = Collection
    template_name = 'collection/collection_list.html'
    display_mode = 'list'

    @method_decorator(last_modified(view_helpers.collections_modified))
    def dispatch(self, *args, **kwargs):
        return super(CollectionList, self).dispatch(*args, **kwargs)

    def get_queryset(self):
        solr = solr_interface()
        solrq = solr.query(content_model=Collection.COLLECTION_CONTENT_MODEL) \
                    .sort_by('title_exact') \
                    .results_as(SolrCollection)

        # optional collection owner in settings; if set, filter collections
        # by the specified owner
        collection_owner = getattr(settings, 'COLLECTIONS_OWNER', None)
        if collection_owner:
            solrq = solrq.filter(owner=collection_owner)

        return solrq

    def get_context_data(self, **kwargs):
        solr = solr_interface()
        q = solr.query(content_model=Volume.VOLUME_CMODEL_PATTERN) \
                .facet_by('collection_id', sort='count', mincount=1) \
                .paginate(rows=0)
        facets = q.execute().facet_counts.facet_fields
        # convert into dictionary for access by pid
        collection_counts = dict([(pid, total)
                                  for pid, total in facets['collection_id']])
        # generate a list of tuple of solr result, volume count,
        # filtering out any collections with no items
        collections = [(r, collection_counts.get(r['pid']))
                       for r in self.object_list
                       if r['pid'] in collection_counts]

        # generate a random list of 4 covers for use in twitter gallery card
        # - restrict to collections with cover images
        covers = [coll.cover for coll, count in collections if coll.cover]
        # - randomize the list in place so we can grab the first N
        shuffle(covers)

        return {
            'collections': collections,
            'mode': self.display_mode,
            'meta_covers': covers[:4]
        }
Example #9
0
 def list(self, request):
     def get_last_modified(request):
         try:
             latest_wortwurst = self.filter_qs.latest('created').created
         except Wortwurst.DoesNotExist:
             latest_wortwurst = epoch
         try:
             latest_vote = Vote.objects.latest('created').created
         except Vote.DoesNotExist:
             latest_vote = epoch
         return max(latest_wortwurst, latest_vote)
     return last_modified(get_last_modified)(
         super(WortwurstViewSet, self).list
     )(request)
Example #10
0
 def index(self, request, pk=None):
     def get_last_modified(request):
         return timezone.make_aware(
             datetime.datetime.utcfromtimestamp(os.stat(__file__).st_mtime)
         )
     return last_modified(get_last_modified)(
         lambda request: render(request, 'wortwurster/main/index.html', {
             'title': "Wortwurster",
             'filters': get_filters(self.filter, self.vote_types),
             'sortings': get_sortings(self.sorting),
             'vote_types': self.vote_types,
             'random_texts': get_random_lines(20, 480),
             'id': pk,
         })
     )(request)
Example #11
0
 def retrieve(self, request, pk):
     def get_last_modified(request, pk):
         wortwurst = self.get_object()
         try:
             latest_wortwurst = wortwurst.created
         except Wortwurst.DoesNotExist:
             latest_wortwurst = epoch
         try:
             latest_vote = wortwurst.vote_set.latest('created').created
         except Vote.DoesNotExist:
             latest_vote = epoch
         return max(latest_wortwurst, latest_vote)
     return last_modified(get_last_modified)(
         super(WortwurstViewSet, self).retrieve
     )(request, pk)
Example #12
0
    def as_view(cls, **kws):
        V = super(LastMod, cls).as_view(**kws)

        if 'time_sk' in kws:
            collection_name = kws['collection_name']
            sk = kws['time_sk']
            vk = kws.get('time_vk') or sk
            def _modtime(req, *args, **kws):
                coll = req.mongodb[collection_name]
                O = coll.find_one(None, fields={vk:1},
                                  sort=[(sk,-1)])
                if not O:
                    return None
                else:
                    return O[vk]

            V = last_modified(_modtime)(V)
        return never_cache(V)
Example #13
0
    def as_view(cls, **initkwargs):
        view = patched_view = super().as_view(**initkwargs)
        last_modified_evaluator = functools.lru_cache()(cls.last_modified)
        patched_view = last_modified(last_modified_evaluator)(patched_view)
        patched_view = cache_control(**cls.cache_control())(patched_view)
        patched_view = cache_page(
            None, key_prefix=last_modified_evaluator  # will be used value of Cache-Control.max-age or default one
        )(patched_view)
        view = conditional(cls.cache_headers_allowed, patched_view)(view)

        @functools.wraps(cls.as_view)
        def logging_view(request, *args, **kwargs):

            request_logger.debug(
                "request_method: %(request_method)s, "
                "request_path: %(request_path)s, "
                "request_headers: %(request_headers)s, "
                "request_params: %(request_params)s, "
                "request_data: %(request_data)s, ",
                dict(
                    request_method=request.method,
                    request_path=request.path,
                    request_headers=request.META,
                    request_params=request.GET,
                    request_data=request.POST,
                ),
            )

            response = view(request, *args, **kwargs)

            response_logger.debug(
                "response_code: %(response_code)s, "
                "response_headers: %(response_headers)s, "
                "response_data: %(response_data)s",
                dict(
                    response_code=response.status_code,
                    response_headers=response.items(),
                    response_data=response.content,
                ),
            )

            return response

        return logging_view
Example #14
0
    def as_view(cls, **initkwargs):
        view = patched_view = super().as_view(**initkwargs)
        last_modified_evaluator = functools.lru_cache()(cls.last_modified)
        patched_view = last_modified(last_modified_evaluator)(patched_view)
        patched_view = cache_page(
            lazy(cls.expires, int)(),
            key_prefix=last_modified_evaluator,
        )(patched_view)
        view = conditional(cls.cache_headers_allowed, patched_view)(view)

        @functools.wraps(cls.as_view)
        def logging_view(request, *args, **kwargs):

            request_logger.debug(
                'request_method: %(request_method)s, '
                'request_path: %(request_path)s, '
                'request_headers: %(request_headers)s, '
                'request_params: %(request_params)s, '
                'request_data: %(request_data)s, ',
                dict(
                    request_method=request.method,
                    request_path=request.path,
                    request_headers=request.META,
                    request_params=request.GET,
                    request_data=request.POST,
                ),
            )

            response = view(request, *args, **kwargs)

            response_logger.debug(
                'response_code: %(response_code)s, '
                'response_headers: %(response_headers)s, '
                'response_data: %(response_data)s',
                dict(
                    response_code=response.status_code,
                    response_headers=response.items(),
                    response_data=response.content,
                ),
            )

            return response

        return logging_view
Example #15
0
class ProductVersionView(ListView):
    template_name = 'security/product-advisories.html'
    context_object_name = 'product_versions'
    allow_empty = False

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(ProductVersionView, self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        slug = self.kwargs['slug']
        qfilter = Q(slug__startswith=slug + '.')
        dots = slug.count('.')
        if dots == 1:
            # minor version. add exact match.
            qfilter |= Q(slug__exact=slug)
        versions = Product.objects.filter(qfilter)
        return sorted(versions, reverse=True)
Example #16
0
class ProductVersionView(ListView):
    template_name = 'security/product-advisories.html'
    context_object_name = 'product_versions'
    allow_empty = False

    @method_decorator(cache_control_expires(0.5))
    @method_decorator(last_modified(latest_advisory))
    def dispatch(self, request, *args, **kwargs):
        return super(ProductVersionView,
                     self).dispatch(request, *args, **kwargs)

    def get_queryset(self):
        slug = self.kwargs['slug']
        qfilter = Q(slug__startswith=slug + '.')
        dots = slug.count('.')
        if dots < 2:
            # add exact match if not point release
            if slug.endswith('.0'):
                # stip trailing .0 as products are stored without them
                slug = slug[:-2]
            qfilter |= Q(slug__exact=slug)
        versions = Product.objects.filter(qfilter)
        return sorted(versions, reverse=True)
Example #17
0
                                'error': reason,
                            }

                        break
                if not ret:
                    ret = {
                        'error': ugettext(
                            "All IOTD slots for the next %(days)s days are already filled."
                        ) % {
                            'days': max_days,
                        },
                    }
            return self.render_json_response(ret)

        return HttpResponseForbidden()


@method_decorator([
    cache_page(3600),
    last_modified(CachingService.get_latest_iotd_datetime),
    cache_control(private=True), vary_on_cookie
],
                  name='dispatch')
class IotdArchiveView(ListView):
    model = Iotd
    template_name = 'astrobin_apps_iotd/iotd_archive.html'
    paginate_by = 30

    def get_queryset(self):
        return IotdService().get_iotds()
Example #18
0
# -*- coding:utf-8 -*-
from django.views.decorators.http import condition, etag, last_modified
from django.http import HttpResponse

from models import FULL_RESPONSE, LAST_MODIFIED, ETAG

def index(request):
    return HttpResponse(FULL_RESPONSE)
index = condition(lambda r: ETAG, lambda r: LAST_MODIFIED)(index)

def last_modified_view1(request):
    return HttpResponse(FULL_RESPONSE)
last_modified_view1 = condition(last_modified_func=lambda r: LAST_MODIFIED)(last_modified_view1)

def last_modified_view2(request):
    return HttpResponse(FULL_RESPONSE)
last_modified_view2 = last_modified(lambda r: LAST_MODIFIED)(last_modified_view2)

def etag_view1(request):
    return HttpResponse(FULL_RESPONSE)
etag_view1 = condition(etag_func=lambda r: ETAG)(etag_view1)

def etag_view2(request):
    return HttpResponse(FULL_RESPONSE)
etag_view2 = etag(lambda r: ETAG)(etag_view2)

Example #19
0
from django.views.i18n import JavaScriptCatalog

from . import views
from ...users.forms.auth import AdminAuthenticationForm

admin.autodiscover()
admin.site.login_form = AdminAuthenticationForm

urlpatterns = [
    url(r"^", include("social_django.urls", namespace="social")),
    url(r"^forum/", include("misago.urls", namespace="misago")),
    url(r"^django-admin/", admin.site.urls),
    url(
        r"^django-i18n.js$",
        cache_page(86400 * 2, key_prefix="misagojsi18n")(
            last_modified(lambda req, **kw: timezone.now())(
                JavaScriptCatalog.as_view(packages=["misago"]))),
        name="django-i18n",
    ),
    # django-simple-sso doesn't have namespaces, we can't use namespace here
    url(r"^sso/", include("misago.sso.urls")),
    url(r"^forum/test-pagination/$",
        views.test_pagination,
        name="test-pagination"),
    url(
        r"^forum/test-pagination/(?P<page>[1-9][0-9]*)/$",
        views.test_pagination,
        name="test-pagination",
    ),
    url(
        r"^forum/test-paginated-response/$",
        views.test_paginated_response,
Example #20
0
from apps.survey.layer_context import get_group_territory_modification_time

#####################################
# PROGRESS PAGE ROUTES
#####################################

progress_page = route(GET=do(render_template('survey/progress.html'),
                             v.progress_page))

progress_page_blockface_popup = route(
    GET=do(
        render_template('survey/partials/progress_page_blockface_popup.html'),
        v.progress_page_blockface_popup))

group_borders_geojson = do(
    last_modified(get_group_territory_modification_time),
    route(GET=json_api_call(v.group_borders_geojson)))

group_popup = route(GET=do(group_request,
                           render_template('survey/partials/group_popup.html'),
                           v.group_popup))

#####################################
# RESERVATION ROUTES
#####################################

printable_reservations_map = route(
    GET=do(
        login_required,
        render_template('survey/printable_reservations_map.html'),
        v.printable_reservations_page))
Example #21
0
class CoverArt(View):
    def __init__(self):
        self.storage = LOGO_STORAGE

    @method_decorator(last_modified(_last_modified))
    def get(self, request, size, prefix, filename):

        size = int(size)

        prefix = get_prefix(filename)
        target = self.get_thumbnail_path(size, prefix, filename)
        original = self.get_original_path(prefix, filename)

        if self.storage.exists(target):
            return self.send_file(target)

        if not self.storage.exists(original):
            logger.warning('Original cover {} not found'.format(original))
            raise Http404('Cover Art not available' + original)

        target_dir = self.get_dir(filename)
        try:
            fp = self.storage.open(original, 'rb')
            im = Image.open(fp)
            if im.mode not in ('RGB', 'RGBA'):
                im = im.convert('RGBA')
        except IOError as ioe:
            logger.warning('Cover file {} cannot be opened: {}'.format(
                original, ioe))
            raise Http404('Cannot open cover file') from ioe

        try:
            im.thumbnail((size, size), Image.ANTIALIAS)
            resized = im
        except (struct.error, IOError, IndexError) as ex:
            # raised when trying to read an interlaced PNG;
            logger.warning('Could not create thumbnail: %s', str(ex))

            # we use the original instead
            return self.send_file(original)

        sio = io.BytesIO()

        try:
            resized.save(sio,
                         'JPEG',
                         optimize=True,
                         progression=True,
                         quality=80)
        except IOError as ex:
            return self.send_file(original)
        finally:
            fp.close()

        self.storage.save(target, sio)

        return self.send_file(target)

    @staticmethod
    def get_thumbnail_path(size, prefix, filename):
        return os.path.join('logo', str(size), prefix, filename)

    @staticmethod
    def get_dir(filename):
        return os.path.dirname(filename)

    @staticmethod
    def remove_existing_thumbnails(prefix, filename):
        dirs, _files = LOGO_STORAGE.listdir(
            'logo')  # TODO: cache list of sizes
        for size in dirs:
            if size == 'original':
                continue

            path = os.path.join('logo', size, prefix, filename)
            logger.info('Removing {}'.format(path))
            LOGO_STORAGE.delete(path)

    @staticmethod
    def get_original_path(prefix, filename):
        return os.path.join('logo', 'original', prefix, filename)

    def send_file(self, filename):
        return HttpResponseRedirect(LOGO_STORAGE.url(filename))

    @classmethod
    def save_podcast_logo(cls, cover_art_url):
        if not cover_art_url:
            return

        try:
            image_sha1 = hashlib.sha1(
                cover_art_url.encode('utf-8')).hexdigest()
            prefix = get_prefix(image_sha1)

            filename = cls.get_original_path(prefix, image_sha1)
            dirname = cls.get_dir(filename)

            # get hash of existing file
            if LOGO_STORAGE.exists(filename):
                with LOGO_STORAGE.open(filename, 'rb') as f:
                    old_hash = file_hash(f).digest()
            else:
                old_hash = ''

            logger.info('Logo {}, saving to {}'.format(cover_art_url,
                                                       filename))

            # save new cover art
            LOGO_STORAGE.delete(filename)
            source = io.BytesIO(requests.get(cover_art_url).content)
            LOGO_STORAGE.save(filename, source)

            # get hash of new file
            with LOGO_STORAGE.open(filename, 'rb') as f:
                new_hash = file_hash(f).digest()

            # remove thumbnails if cover changed
            if old_hash != new_hash:
                logger.info('Removing thumbnails')
                thumbnails = cls.remove_existing_thumbnails(prefix, filename)

            return cover_art_url

        except (
                ValueError,
                requests.exceptions.RequestException,
                socket.error,
                IOError,
        ) as e:
            logger.warning('Exception while updating podcast logo: %s', str(e))
Example #22
0
from django.views.generic import TemplateView
from django.views import i18n

from horizon.test.jasmine import jasmine
from horizon import views

urlpatterns = [
    url(r'^home/$', views.user_home, name='user_home')
]

last_modified_date = timezone.now()

# Client-side i18n URLconf.
urlpatterns.extend([
    url(r'^i18n/js/(?P<packages>\S+?)/$',
        last_modified(lambda req, **kw: last_modified_date)(
            i18n.JavaScriptCatalog.as_view()),
        name='jsi18n'),
    url(r'^i18n/setlang/$',
        i18n.set_language,
        name="set_language"),
    url(r'^i18n/', include('django.conf.urls.i18n'))
])

if settings.DEBUG:
    urlpatterns.extend([
        url(r'^jasmine-legacy/$',
            TemplateView.as_view(
                template_name="horizon/jasmine/jasmine_legacy.html"),
            name='jasmine_tests'),
        url(r'^jasmine/.*?$', jasmine.dispatcher),
    ])
Example #23
0
        context['most_popular_html'] = \
            models.MostPopular.get_most_popular_html()
        return context

    # LEAVE THIS COMMENTED OUT CODE IN CASE OF EMERGENCY IN
    # WHICH CODE NEEDS TO CHANGE URGENTLY.

    def get(self, request, *args, **kwargs):
           # Add messages here. E.g.
           messages.add_message(request, messages.INFO,
                                "We're only publishing urgent news until 10 January. Have a safe holiday season.")
           request = super(HomePage, self).get(request, args, kwargs)
           return request

home_page_view = HomePage.as_view()
home_page_view = last_modified(last_article_modified)(home_page_view)


class OpinionAnalysisList(ArticleList):

    def get_queryset(self):
        return models.Article.objects.list_view().filter(
            Q(category__name="Opinion") |
            Q(category__name="Analysis"))

    def get_context_data(self, **kwargs):
        context = super(OpinionAnalysisList, self).get_context_data(**kwargs)
        context['heading'] = "Opinion and Analysis"
        return context

Example #24
0
class CollectionDetail(DetailView, VaryOnCookieMixin):
    '''View a single collection, with a paginated list of the volumes
    it includes (volumes sorted by title and then ocm number/volume).
    '''
    model = Collection
    template_name = 'collection/collection_detail.html'
    context_object_name = 'collection'
    display_mode = 'list'

    @method_decorator(last_modified(view_helpers.collection_modified))
    def dispatch(self, *args, **kwargs):
        return super(CollectionDetail, self).dispatch(*args, **kwargs)

    def get_object(self, queryset=None):
        # kwargs are set based on configured url pattern
        pid = self.kwargs['pid']
        repo = Repository(request=self.request)
        obj = repo.get_object(pid, type=Collection)
        # if pid doesn't exist or isn't a collection, 404
        if not obj.exists or not obj.has_requisite_content_models:
            raise Http404
        return obj

    def get_context_data(self, **kwargs):
        context_data = super(CollectionDetail, self).get_context_data()
        # sort: currently supports title or date added
        sort = self.request.GET.get('sort', None)

        if self.request.user.is_authenticated():
            notes = Volume.volume_annotation_count(self.request.user)
            domain = get_current_site(self.request).domain.rstrip('/')
            if not domain.startswith('http'):
                domain = 'http://' + domain
            annotated_volumes = dict([(k.replace(domain, ''), v)
                                      for k, v in notes.iteritems()])
        else:
            annotated_volumes = {}

        # search for all books that are in this collection
        solr = solr_interface()
        q = solr.query(content_model=Volume.VOLUME_CMODEL_PATTERN,
                       collection_id=self.object.pid) \
                .results_as(SolrVolume)

        # url parameters for pagination and facet links
        url_params = self.request.GET.copy()

        # generate list for display and removal of active filters
        # NOTE: borrowed from books.view.search
        display_filters = []
        # active filter - only show volumes with pages loaded
        if 'read_online' in self.request.GET and self.request.GET[
                'read_online']:
            q = q.query(page_count__gte=2)

            unfacet_urlopts = url_params.copy()
            del unfacet_urlopts['read_online']
            display_filters.append(
                ('Read online', '', unfacet_urlopts.urlencode()))
        else:
            # generate a facet count for books with pages loaded
            q = q.facet_query(page_count__gte=2)

        sort_options = ['title', 'date added']
        if sort not in sort_options:
            # by default, sort by title
            sort = 'title'

        if sort == 'title':
            # sort by title and then by label so multi-volume works should group
            # together in the correct order
            q = q.sort_by('title_exact').sort_by('label')
        elif sort == 'date added':
            # sort by most recent creation date (newest additions first)
            q = q.sort_by('-created')

        # paginate the solr result set
        paginator = Paginator(q, 30)
        try:
            page = int(self.request.GET.get('page', '1'))
        except ValueError:
            page = 1
        try:
            results = paginator.page(page)
        except (EmptyPage, InvalidPage):
            results = paginator.page(paginator.num_pages)

        # facets for diplay
        facet_counts = results.object_list.facet_counts
        facets = {}
        if facet_counts.facet_queries:
            # number of volumes with pages loaded;
            # facet query is a list of tuple; second value is the count
            pages_loaded = facet_counts.facet_queries[0][1]
            if pages_loaded < q.count():
                facets['pages_loaded'] = facet_counts.facet_queries[0][1]

        # url parameters for pagination & sort links
        url_params = self.request.GET.copy()
        if 'page' in url_params:
            del url_params['page']
        sort_url_params = self.request.GET.copy()
        if 'sort' in sort_url_params:
            del sort_url_params['sort']

        context_data.update({
            'items':
            results.object_list,
            'mode':
            self.display_mode,
            'url_params':
            urlencode(url_params),
            'sort_url_params':
            urlencode(sort_url_params),
            'current_url_params':
            urlencode(self.request.GET.copy()),
            'sort':
            sort,
            'sort_options':
            sort_options,
            'annotated_volumes':
            annotated_volumes,
            'facets':
            facets,  # available facets
            'filters':
            display_filters,  # active filters
            # for compatibility with class-based view pagination
            'paginator':
            paginator,
            'page_obj':
            results,
        })
        return context_data
Example #25
0
class PageDetail(DetailView, VaryOnCookieMixin):
    '''View a single page in a book.'''
    model = Page
    template_name = 'books/page_detail.html'
    context_object_name = 'page'

    @method_decorator(last_modified(view_helpers.page_modified))
    def dispatch(self, *args, **kwargs):
        return super(PageDetail, self).dispatch(*args, **kwargs)

    def get_object(self, queryset=None):
        # NOTE: type inferring repository needed to load pages as correct type
        # of Page (v1.0 or v1.1)
        repo = TypeInferringRepository(request=self.request)
        page = repo.get_object(self.kwargs['pid'])
        if not page.exists or not isinstance(page, Page):
            raise Http404
        return page

    def get_context_data(self, **kwargs):
        context_data = super(PageDetail, self).get_context_data()
        # use solr to find adjacent pages to this one
        pagequery = self.object.volume.find_solr_pages()
        # search range around current page order
        # (+/-1 should probably work, but using 2 to allow some margin for error)
        pagequery = pagequery.query(
            page_order__range=(self.object.page_order - 2,
                               self.object.page_order + 2))

        # find the index of the current page in the sorted solr result
        index = 0
        prev = nxt = None
        for p in pagequery:
            if p['pid'] == self.object.pid:
                break
            index += 1
            prev = p

        if len(pagequery) > index + 1:
            nxt = pagequery[index + 1]

        # calculates which paginated page the page is part of based on 30 items per page
        page_chunk = ((self.object.page_order - 1) // 30) + 1

        # form for searching in this book
        form = BookSearch()

        # currently only pagev1_1 has tei
        if hasattr(self.object, 'tei') and self.object.tei.exists:
            # determine scale for positioning OCR text in TEI facsimile
            # based on original image size in the OCR and image as displayed
            # - find maximum of width/height
            long_edge = max(self.object.tei.content.page.width,
                            self.object.tei.content.page.height)
            # NOTE: using the size from image the OCR was run on, since that
            # may or may not match the size of the master image loaded in
            # fedora, but the aspect ration should be kept the same from
            # original -> repository copy -> scaled copy used for display

            # - determine scale to convert original size to display size
            scale = float(SINGLE_PAGE_SIZE) / float(long_edge)
            logger.debug('page size is %s, long edge is %s, scale is %f' % \
                (SINGLE_PAGE_SIZE, long_edge, scale))
        else:
            scale = None

        context_data.update({
            'next': nxt,
            'prev': prev,
            'page_chunk': page_chunk,
            'form': form,
            'scale': scale
        })

        # if user is logged in, check for zotero account and pass
        # token and user id through for annotation citation
        if not self.request.user.is_anonymous():
            zotero_account = self.request.user.social_auth.filter(
                provider='zotero').first()
            if zotero_account:
                context_data.update({
                    'zotero_userid':
                    zotero_account.extra_data['access_token']['userID'],
                    'zotero_token':
                    zotero_account.extra_data['access_token']['oauth_token']
                })

            # if user is logged in, check if annotations exist and
            # search should be enabled
            context_data['annotation_search_enabled'] = \
                self.object.volume.annotations() \
                    .visible_to(user=self.request.user).exists()

        return context_data
Example #26
0
                CategoryOptionsViewSet,
                basename='category')
router.register(r'type-attachment',
                TypeAttachmentViewSet,
                basename='type-attachment')
router.register(r'thesis-year-options',
                ThesisYearViewSet,
                basename='thesis-year')
router.register(r'reservation-state-options',
                ReservationStateOptionsViewSet,
                basename='reservation-state')
router.register(r'thesis-state-options',
                ThesisStateOptionsViewSet,
                basename='thesis-state')

app_name = 'api'
urlpatterns = [
    path('v1/', include((router.urls, 'v1'))),
    path('v1/login', LoginView.as_view()),
    path('v1/dashboard', DashboardView.as_view()),
    path('v1/has-perm/<str:perm>', UserPermView.as_view(), name='has-perm'),
    path('v1/review-pdf-detail/<uuid:pk>',
         ReviewPdfView.as_view(),
         name='review-pdf-detail'),
    path(
        'i18n/catalog',
        last_modified(lambda req, **kw: last_modified_date)(
            JSONCatalog.as_view(domain='django'))),
    path('i18n/', include('django.conf.urls.i18n')),
]
Example #27
0
from django.http import HttpResponse, HttpResponseForbidden
from django.shortcuts import get_object_or_404
from django.views.decorators.http import last_modified, require_safe
from django.views.decorators.cache import cache_page

from rest_framework import generics
from rest_framework.authtoken.models import Token
from rest_framework.viewsets import ModelViewSet
from synctool.routing import Route

from . import models, serializers
from .utils import get_last_modified_date, HttpResponseJSON


rnasync = Route(api_token=None).app('rna', 'rna')
rnasync = last_modified(get_last_modified_date)(rnasync)
RNA_JSON_CACHE_TIME = getattr(settings, 'RNA_JSON_CACHE_TIME', 600)


def auth_token(request):
    if request.user.is_active and request.user.is_staff:
        token, created = Token.objects.get_or_create(user=request.user)
        return HttpResponse(
            content=json.dumps({'token': token.key}),
            content_type='application/json')
    else:
        return HttpResponseForbidden()


class NoteViewSet(ModelViewSet):
    queryset = models.Note.objects.all()
Example #28
0
def cache(view):
    return last_modified(lambda req, **kw: last_modified_date)(view)
Example #29
0
from . import views
from ...users.forms.auth import AdminAuthenticationForm

admin.autodiscover()
admin.site.login_form = AdminAuthenticationForm

urlpatterns = [
    url(r"^", include("social_django.urls", namespace="social")),
    url(r"^forum/", include("misago.urls", namespace="misago")),
    url(r"^django-admin/", admin.site.urls),
    url(
        r"^django-i18n.js$",
        cache_page(86400 * 2, key_prefix="misagojsi18n")(
            last_modified(lambda req, **kw: timezone.now())(
                JavaScriptCatalog.as_view(packages=["misago"])
            )
        ),
        name="django-i18n",
    ),
    url(r"^forum/test-pagination/$", views.test_pagination, name="test-pagination"),
    url(
        r"^forum/test-pagination/(?P<page>[1-9][0-9]*)/$",
        views.test_pagination,
        name="test-pagination",
    ),
    url(
        r"^forum/test-paginated-response/$",
        views.test_paginated_response,
        name="test-paginated-response",
    ),
Example #30
0
    def get_parent_object(self):
        return get_shared_key(self.request, *self.args, **self.kwargs)

    def get_doc(self):
        key = self.get_parent_object()
        qs = self.model.objects.filter(dataset=key.exhibit.dataset)
        return qs.values_list("data", flat=True)[0]

    def check_perms(self):
        key = self.get_parent_object()
        return key.exhibit.dataset_available(key.exhibit.owner)

def _dataset_modified(r, *a, **kwa):
    key = get_shared_key(r, *a, **kwa)
    return key.exhibit.dataset.modified
_lm = last_modified(_dataset_modified)

shared_dataset_profile_json = _lm(SharedKeyDatasetJSONView.as_view(model=dataset_models.DatasetProfile))
shared_dataset_data_json = _lm(SharedKeyDatasetJSONView.as_view(model=dataset_models.DatasetJSONFile))
shared_dataset_properties_json = _lm(SharedKeyDatasetJSONView.as_view(model=dataset_models.DatasetPropertiesCache))


#-----------------------------------------------------------------------------#
# Shared exhibit profile json

class SharedExhibitProfileJSONView(BaseJSONView):
    """
    Returns the exhibit profile associated with a particular shared key.

    There is no permissions check, as the owner of the key is the owner
    of the exhibit.
Example #31
0
            content_type='text/html',
        )),
        kwargs={'announcements':Announcement.objects.all()},
        name='info',
    ),

    url(r'^info/links/$',
        never_cache(TemplateView.as_view(
            template_name='pages/links.html',
            content_type='text/html',
        )),
        name='links',
    ),

    url(r'^about/$',
        cache_page(60*5)(last_modified(fp_lastmod)(flatpage)),
        #cache_page(60*5)(flatpage),
        kwargs={'url': '/about/'},
        name='about'
    ),

    url(r'^about/privacy/$',
        cache_page(60*5)(last_modified(fp_lastmod)(flatpage)),
        kwargs={'url': '/about/privacy/'},
        name='privacy'
    ),

    url(r'^about/terms/$',
        cache_page(60*5)(last_modified(fp_lastmod)(flatpage)),
        kwargs={'url': '/about/terms/'},
        name='terms'
Example #32
0
class VolumeSearch(ListView):
    '''Search across all volumes.'''

    model = Volume
    template_name = 'books/volume_search.html'
    paginate_by = 10
    context_object_name = 'items'

    display_mode = 'list'
    display_filters = []
    sort_options = ['relevance', 'title', 'date added']

    @method_decorator(last_modified(view_helpers.volumes_modified))
    def dispatch(self, *args, **kwargs):
        return super(VolumeSearch, self).dispatch(*args, **kwargs)

    def get_queryset(self):
        self.form = BookSearch(self.request.GET)

        # sort: currently supports relevance, title, or date added
        self.sort = self.request.GET.get('sort', None)

        if self.form.is_valid():
            # get list of keywords and phrases
            terms = self.form.search_terms()
            solr = solr_interface()
            # generate queries text and boost-field queries
            text_query = solr.Q()
            author_query = solr.Q()
            title_query = solr.Q()
            for t in terms:
                text_query |= solr.Q(t)
                author_query |= solr.Q(creator=t)
                title_query |= solr.Q(title=t)

            q = solr.query().filter(content_model=Volume.VOLUME_CMODEL_PATTERN) \
                    .query(text_query | author_query**3 | title_query**3) \
                    .field_limit(SolrVolume.necessary_fields, score=True)  \
                    .results_as(SolrVolume)

            if self.sort not in self.sort_options:
                # by default, sort by relevance score
                self.sort = 'relevance'
            if self.sort == 'relevance':
                q = q.sort_by('-score')
            elif self.sort == 'title':
                # sort by title and then by label so multi-volume works should group
                # together in the correct order
                q = q.sort_by('title_exact').sort_by('label')
            elif self.sort == 'date added':
                q = q.sort_by('-created')

            url_params = self.request.GET.copy()

            # don't need to facet on collection if we are already filtered on collection
            if 'collection' not in self.request.GET:
                q = q.facet_by('collection_label_facet',
                               sort='index',
                               mincount=1)

            self.display_filters = []
            if 'collection' in self.request.GET:
                filter_val = self.request.GET['collection']
                # filter the solr query based on the requested collection
                q = q.query(collection_label='"%s"' % filter_val)
                # generate link to remove the facet
                unfacet_urlopts = url_params.copy()
                del unfacet_urlopts['collection']
                self.display_filters.append(
                    ('collection', filter_val, unfacet_urlopts.urlencode()))

            # active filter - only show volumes with pages loaded
            if 'read_online' in self.request.GET and self.request.GET[
                    'read_online']:
                q = q.query(page_count__gte=2)
                unfacet_urlopts = url_params.copy()
                del unfacet_urlopts['read_online']
                self.display_filters.append(
                    ('Read online', '', unfacet_urlopts.urlencode()))
            else:
                # generate a facet count for books with pages loaded
                q = q.facet_query(page_count__gte=2)

            return q

        else:
            # empty 'queryset' result required by view methods
            return []

    def get_context_data(self):
        context_data = super(VolumeSearch, self).get_context_data()

        url_params = self.request.GET.copy()
        sort_url_params = self.request.GET.copy()
        if 'sort' in sort_url_params:
            del sort_url_params['sort']

        context_data.update({
            'form':
            self.form,
            'url_params':
            urlencode(url_params),
            'mode':
            self.display_mode,  # list / cover view
            'current_url_params':
            urlencode(self.request.GET.copy()),
            'sort':
            self.sort,
            'sort_options':
            self.sort_options,
            'sort_url_params':
            urlencode(sort_url_params),
        })

        # get facets and annotations IF there are are any search results
        if context_data['object_list']:
            # adjust facets as returned from solr for display
            facet_counts = context_data['object_list'].facet_counts
            facets = {}
            collections = facet_counts.facet_fields.get(
                'collection_label_facet', [])
            # only include collections in facet if there are any
            if collections:
                facets['collection'] = collections
            if facet_counts.facet_queries:
                # number of volumes with pages loaded;
                # facet query is a list of tuple; second value is the count
                pages_loaded = facet_counts.facet_queries[0][1]
                # only display if it is a facet, i.e. not all volumes
                # in the result set have pages loaded
                if pages_loaded < context_data['paginator'].count:
                    facets['pages_loaded'] = facet_counts.facet_queries[0][1]

            # generate list for display and removal of active filters
            q = self.get_queryset()
            annotated_volumes = {}
            if context_data[
                    'paginator'].count and self.request.user.is_authenticated(
                    ):
                notes = Volume.volume_annotation_count(self.request.user)
                domain = get_current_site(self.request).domain.rstrip('/')
                if not domain.startswith('https'):
                    domain = 'https://' + domain
                annotated_volumes = dict([(k.replace(domain, ''), v)
                                          for k, v in notes.iteritems()])

            context_data.update({
                'facets': facets,  # available facets
                'filters': self.display_filters,  # active filters
                'annotated_volumes': annotated_volumes
            })

        return context_data
Example #33
0
     name="api-notification",
     kwargs={'action': 'count'},
 ),
 url(
     r'^api/notification/(?P<app>[\w]+)/(?P<model>[\w]+)/list/$',
     never_cache(
         NotificationListAPI.as_view()
     ),
     name="api-notification",
     kwargs={'action': 'list'},
 ),
 url(
     r'^api/view/(?P<db>[\w-]+)/(?P<cat>[\w-]+)/(?P<view>[\w-]+)/$',
     cache_page(CACHE_TIME, key_prefix=VERSION)(
         last_modified(lambda req, **kw: now())(
             APIViewDetail.as_view()
         )
     ),
     name="api-view",
 ),
 url(
     r'^api/documents/(?P<app>[\w]+)/(?P<model>[\w]+)/(?P<pk>[0-9]+)/$',
     APIDocumentsView.as_view({'get': 'list', 'post': 'create'}),
     name="api-documents",
 ),
 url(
     r'^api/documents/$',
     APIDocumentsView.as_view({'get': 'list', 'post': 'create'}),
     name="api-documents",
 ),
 url(
Example #34
0
            if acquisition_type in Image.ACQUISITION_TYPES:
                queryset = queryset.filter(
                    image__acquisition_type=acquisition_type)

        return queryset

    def get_context_data(self, **kwargs):
        context = super(TopPickBaseView, self).get_context_data(**kwargs)
        context['source'] = self.request.GET.get('source')
        context['acquisition_type'] = self.request.GET.get('acquisition_type')
        return context


@method_decorator([
    cache_page(600),
    last_modified(CachingService.get_latest_top_pick_datetime),
    cache_control(private=True), vary_on_cookie
],
                  name='dispatch')
class TopPicksView(TopPickBaseView):
    model = TopPickArchive
    template_name = 'top_picks.html'
    paginate_by = 30

    def get_queryset(self):
        queryset = IotdService().get_top_picks()
        queryset = self.filter_by_datasource(queryset)
        queryset = self.filter_by_acquisition_type(queryset)
        return queryset

Example #35
0
from django.views.generic.edit import CreateView

from viewshare.apps.share import models
from viewshare.apps.exhibit.models import PublishedExhibit
from viewshare.apps.share import forms


# The last_modified decorator requires a function
from viewshare.utilities.views import BaseJSONView


def _exhibit_modified(r, *a, **kwa):
    qs = models.SharedExhibitKey.objects.filter(slug=kwa["slug"])
    qs = qs.values_list("exhibit__modified", flat=True)[0]
    return qs
_lm = last_modified(_exhibit_modified)


class SharedExhibitDisplayView(DetailView):

    model = models.SharedExhibitKey

    template_name = "share/exhibit_display.html"

    def get_object(self, queryset=None):
        if queryset is None:
            queryset = self.get_queryset()
        queryset = queryset.select_related("exhibit__owner")
        obj = get_object_or_404(queryset, slug=self.kwargs.get("slug"))
        return obj
Example #36
0
from viewshare.apps.share import models
from viewshare.apps.exhibit.models import PublishedExhibit
from viewshare.apps.share import forms

# The last_modified decorator requires a function
from viewshare.utilities.views import BaseJSONView


def _exhibit_modified(r, *a, **kwa):
    qs = models.SharedExhibitKey.objects.filter(slug=kwa["slug"])
    qs = qs.values_list("exhibit__modified", flat=True)[0]
    return qs


_lm = last_modified(_exhibit_modified)


class SharedExhibitDisplayView(DetailView):

    model = models.SharedExhibitKey

    template_name = "share/exhibit_display.html"

    def get_object(self, queryset=None):
        if queryset is None:
            queryset = self.get_queryset()
        queryset = queryset.select_related("exhibit__owner")
        obj = get_object_or_404(queryset, slug=self.kwargs.get("slug"))
        return obj
Example #37
0
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
from django.conf.urls.i18n import i18n_patterns
from authentication.views import index_page, language_changes
from .api import router
from django.views.i18n import JavaScriptCatalog
from django.utils import timezone
from django.views.decorators.http import last_modified

last_modified_date = timezone.now()

urlpatterns = [
    path('jsi18n/',
         last_modified(lambda req, **kw: last_modified_date)(
             JavaScriptCatalog.as_view()),
         name='javascript-catalog'),
    path('', index_page, name="auth_index_view"),
    path('lang_choose', language_changes, name='language_changes'),
    path('admin/', admin.site.urls),
    path('fleet/', include('fleet.urls')),
    path('authentication/', include('authentication.urls')),
    path('api/', include(router.urls))
]
Example #38
0
                                       OwnerSlugPermissionMixin,
                                       OwnerListView)


def get_published_exhibit(request, owner, slug):
    if not hasattr(request, "exhibit"):
        request.exhibit = get_object_or_404(models.PublishedExhibit,
                                            slug=slug, owner__username=owner)
    return request.exhibit


def get_exhibit_modified(request, *args, **kwargs):
    return get_published_exhibit(request,
                                 kwargs["owner"],
                                 kwargs["slug"]).modified
exhibit_last_modified = last_modified(get_exhibit_modified)


class ExhibitDetailEditView(OwnerSlugPermissionMixin, UpdateView):
    form_class = forms.UpdateExhibitDetailForm
    object_perm = "exhibit.can_edit"
    model = models.PublishedExhibit
    template_name = "exhibit/edit/exhibit_metadata_form.html"

    def form_valid(self, form):
        self.object = form.save()

        return HttpResponseRedirect(reverse("exhibit_detail",
                                    kwargs={
                                        "owner": self.object.owner.username,
                                        "slug": self.object.slug
Example #39
0
    # LEAVE THIS COMMENTED OUT CODE IN CASE OF EMERGENCY IN
    # WHICH CODE NEEDS TO CHANGE URGENTLY.

    # def get(self, request, *args, **kwargs):
    # Add messages here. E.g.
    #    messages.add_message(request, messages.INFO,
    #                     "We're only publishing urgent "
    #                     "news until 7 January. Have a "
    #                     "safe holiday season.")
    #    request = super(HomePage, self).get(request, args, kwargs)
    #    return request


home_page_view = HomePage.as_view()
home_page_view = last_modified(last_article_modified)(home_page_view)


class OpinionAnalysisList(ArticleList):

    def get_queryset(self):
        return models.Article.objects.list_view().filter(
            Q(category__name="Opinion") |
            Q(category__name="Analysis"))

    def get_context_data(self, **kwargs):
        context = super(OpinionAnalysisList, self).get_context_data(**kwargs)
        context['heading'] = "Opinion and Analysis"
        return context

Example #40
0
    def check_perms(self):
        if not self.request.user.has_perm("dataset.can_view", self.get_parent_object()):
            return False
        return True

    def cache_control_header(self):
        cache_control = super(DatasetJSONView, self).cache_control_header()
        if not self.get_parent_object().published:
            cache_control += ", private"
        else:
            cache_control += ", public"
        return cache_control


lmdec = last_modified(lambda request, *args, **kwargs: get_request_instance(request, *args, **kwargs).modified)

dataset_profile_json = lmdec(DatasetJSONView.as_view(model=models.DatasetProfile))

dataset_data_json = lmdec(DatasetJSONView.as_view(model=models.DatasetJSONFile))

dataset_properties_json = lmdec(DatasetJSONView.as_view(model=models.DatasetPropertiesCache))

dataset_list_by_owner = OwnerListView.as_view(template_name="dataset/dataset_list_by_owner.html",
                                               model=models.Dataset,
                                               permission = "dataset.can_view",
                                               related=("exhibits","owner"))

#----------------------------------------------------------------------------------------------------------------------#
# Dataset views
Example #41
0

admin.autodiscover()
admin.site.login_form = AdminAuthenticationForm


urlpatterns = [
    url(r'^', include('misago.urls', namespace='misago')),

    # Javascript translations
    url(
        r'^django-i18n.js$',
        last_modified(lambda req, **kw: timezone.now())(
            cache_page(86400 * 2, key_prefix='misagojsi18n')(
                JavaScriptCatalog.as_view(
                    packages=['misago'],
                ),
            ),
        ),
        name='django-i18n',
    ),

    # Uncomment next line if you plan to use Django admin for 3rd party apps
    #url(r'^django-admin/', admin.site.urls),
]


# If debug mode is enabled, include debug toolbar
if settings.DEBUG:
    import debug_toolbar
    urlpatterns += [
Example #42
0
from notification.models import NoticeSetting, NoticeType, NOTICE_MEDIA
from persistent_messages.models import Message
from rest_framework import viewsets, permissions
from rest_framework.decorators import action
from rest_framework.renderers import BrowsableAPIRenderer
from rest_framework.response import Response

from astrobin_apps_notifications.api.filters import NotificationFilter
from astrobin_apps_notifications.api.serializers import NotificationSerializer, NoticeSettingSerializers, \
    NoticeTypeSerializer
from common.permissions import ReadOnly
from common.services.caching_service import CachingService


@method_decorator([
    last_modified(CachingService.get_last_notification_time),
    cache_control(private=True, no_cache=True),
    vary_on_headers('Cookie', 'Authorization')
],
                  name='dispatch')
class NotificationViewSet(viewsets.ModelViewSet):
    serializer_class = NotificationSerializer
    filter_class = NotificationFilter
    permission_classes = [permissions.IsAuthenticated]
    renderer_classes = [BrowsableAPIRenderer, CamelCaseJSONRenderer]
    parser_classes = [CamelCaseJSONParser]
    http_method_names = ['get', 'post', 'head', 'put']

    def get_queryset(self):
        return Message.objects.filter(
            user=self.request.user).order_by('-created')
Example #43
0
 url(
     r'^api/notification/count/$',
     never_cache(NotificationCountAPI.as_view()),
     name="api-notification",
     kwargs={'action': 'count'},
 ),
 url(
     r'^api/notification/(?P<app>[\w]+)/(?P<model>[\w]+)/list/$',
     never_cache(NotificationListAPI.as_view()),
     name="api-notification",
     kwargs={'action': 'list'},
 ),
 url(
     r'^api/view/(?P<db>[\w-]+)/(?P<cat>[\w-]+)/(?P<view>[\w-]+)/$',
     cache_page(CACHE_TIME, key_prefix=VERSION)(
         last_modified(lambda req, **kw: now())(APIViewDetail.as_view())),
     name="api-view",
 ),
 url(
     r'^api/documents/(?P<app>[\w]+)/(?P<model>[\w]+)/(?P<pk>[0-9]+)/$',
     APIDocumentsView.as_view({
         'get': 'list',
         'post': 'create'
     }),
     name="api-documents",
 ),
 url(
     r'^api/documents/$',
     APIDocumentsView.as_view({
         'get': 'list',
         'post': 'create'
Example #44
0
from django.http import HttpResponse, HttpResponseForbidden
from django.shortcuts import get_object_or_404
from django.views.decorators.http import last_modified

from rest_framework import generics
from rest_framework.authtoken.models import Token
from rest_framework.viewsets import ModelViewSet
from synctool.routing import Route

from . import models, serializers
from .utils import get_last_modified_date


rnasync = Route(api_token=None).app('rna', 'rna')
rnasync = last_modified(get_last_modified_date)(rnasync)


def auth_token(request):
    if request.user.is_active and request.user.is_staff:
        token, created = Token.objects.get_or_create(user=request.user)
        return HttpResponse(
            content=json.dumps({'token': token.key}),
            content_type='application/json')
    else:
        return HttpResponseForbidden()


class NoteViewSet(ModelViewSet):
    queryset = models.Note.objects.all()
    serializer_class = serializers.NoteSerializer
Example #45
0
class VolumeDetail(DetailView, VaryOnCookieMixin):
    ''' Landing page for a single :class:`~readux.books.models.Volume`.

    If keyword search terms are specified, searches within the book and
    finds matching pages.
    '''
    model = Volume
    template_name = 'books/volume_detail.html'
    search_template_name = 'books/volume_pages_search.html'
    context_object_name = 'vol'

    @method_decorator(last_modified(view_helpers.volume_modified))
    @method_decorator(vary_on_headers('X-Requested-With')
                      )  # vary on ajax request
    def dispatch(self, *args, **kwargs):
        return super(VolumeDetail, self).dispatch(*args, **kwargs)

    def get_object(self, queryset=None):
        # kwargs are set based on configured url pattern
        pid = self.kwargs['pid']
        repo = Repository(request=self.request)
        vol = repo.get_object(pid, type=Volume)
        if not vol.exists or not vol.is_a_volume:
            raise Http404
        return vol

    def get_template_names(self):
        # search results require a different template
        if self.form.is_valid():
            return self.search_template_name
        return self.template_name

    def get_context_data(self, **kwargs):
        context_data = super(VolumeDetail, self).get_context_data()
        # sort: currently supports title or date added

        self.form = BookSearch(self.request.GET)
        context_data['form'] = self.form
        # if form is valid, then search within the book and display matching pages
        # instead of volume info
        if self.form.is_valid():
            terms = self.form.search_terms()
            solr = solr_interface()
            query = solr.Q()
            for t in terms:
                # NOTE: should this be OR or AND?
                query |= solr.Q(page_text=t)
                if t.isnumeric():
                    query |= solr.Q(page_order=t)**2
                query |= solr.Q(identifier=t)**3
            # search for pages that belong to this book
            q = solr.query().filter(content_model=Page.PAGE_CMODEL_PATTERN,
                                    isConstituentOf=self.object.uri) \
                    .query(query) \
                    .field_limit(['page_order', 'pid', 'identifier'], score=True) \
                    .highlight('page_text', snippets=3) \
                    .sort_by('-score').sort_by('page_order') \
                    .results_as(SolrPage)

            # return highlighted snippets from page text
            # sort by relevance and then by page order

            # paginate the solr result set
            paginator = Paginator(q, 30)
            try:
                page = int(self.request.GET.get('page', '1'))
            except ValueError:
                page = 1
            try:
                results = paginator.page(page)
            except (EmptyPage, InvalidPage):
                results = paginator.page(paginator.num_pages)

            # NOTE: highlight snippets are available at
            # results.object_list.highlighting but are *NOT* currently
            # getting propagated to solrpage objects

            # url parameters for pagination
            url_params = self.request.GET.copy()
            if 'page' in url_params:
                del url_params['page']

            context_data.update({
                'pages': results,
                'url_params': urlencode(url_params),
                # provided for consistency with class-based view pagination
                'paginator': paginator,
                'page_obj': results
            })

        else:
            # if not searching the volume, get annotation count for display
            # - annotation is only possibly on books with pages loaded
            if self.object.has_pages:
                # uses same dictionary lookup form as for browse/search volume
                annotation_count = self.object.annotation_count(
                    self.request.user)
                if annotation_count != 0:
                    context_data['annotated_volumes'] = {
                        self.object.get_absolute_url(): annotation_count
                    }
                # enable annotation search if any annotations are present
                context_data['annotation_search_enabled'] = bool(
                    annotation_count)

        return context_data

    def render_to_response(self, context, **response_kwargs):
        # return json to ajax request or when requested;
        # currently used for annotation related pages autocomplete
        if self.request.is_ajax() or self.request.GET.get('format',
                                                          '') == 'json':
            solr_result = context['pages']
            highlighting = {}
            if solr_result.object_list.highlighting:
                highlighting = solr_result.object_list.highlighting
            data = [
                {
                    'pid':
                    result.pid,
                    # extra logic to handle records where ARK is not
                    # present (should only happen in dev)
                    'uri':
                    next(
                        iter([
                            uri for uri in result['identifier']
                            if 'ark:' in uri
                        ]), ''),
                    'label':
                    'p. %s' % result['page_order'],
                    'thumbnail':
                    reverse('books:page-image',
                            kwargs={
                                'mode': 'mini-thumbnail',
                                'pid': result.pid,
                                'vol_pid': self.object.pid
                            }),
                    'highlights':
                    highlighting.get(result.pid, {}).get('page_text', '')
                } for result in solr_result.object_list
            ]
            return JsonResponse(data, safe=False)
        else:
            return super(VolumeDetail,
                         self).render_to_response(context, **response_kwargs)
Example #46
0
from kirppu.views import index, MobileRedirect

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

js_packages = (
    'kirppu',
)

last_modified_date = timezone.now()

urlpatterns = [
    path('', index, name='home'),
    path(r'kirppu/', include('kirppu.urls', namespace="kirppu")),
    path(r'accounts/', include('kirppuauth.urls', namespace="kirppuauth")),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),

    # Uncomment the next line to enable the admin:
    path(r'admin/', admin.site.urls),
    path(r'i18n/', include('django.conf.urls.i18n')),
    path(r'jsi18n/', last_modified(lambda req, **kw: last_modified_date)(
        JavaScriptCatalog.as_view(packages=js_packages)),
        name="javascript-catalog"),
    re_path(r'^m/?$', MobileRedirect.as_view()),
    path('', include('kompassi_oauth2.urls')),
]
Example #47
0
from django.views.decorators.http import condition, etag, last_modified
from django.http import HttpResponse

from .tests import FULL_RESPONSE, LAST_MODIFIED, ETAG


def index(request):
    return HttpResponse(FULL_RESPONSE)
index = condition(lambda r: ETAG, lambda r: LAST_MODIFIED)(index)


def last_modified_view1(request):
    return HttpResponse(FULL_RESPONSE)
last_modified_view1 = condition(last_modified_func=lambda r: LAST_MODIFIED)(last_modified_view1)


def last_modified_view2(request):
    return HttpResponse(FULL_RESPONSE)
last_modified_view2 = last_modified(lambda r: LAST_MODIFIED)(last_modified_view2)


def etag_view1(request):
    return HttpResponse(FULL_RESPONSE)
etag_view1 = condition(etag_func=lambda r: ETAG)(etag_view1)


def etag_view2(request):
    return HttpResponse(FULL_RESPONSE)
etag_view2 = etag(lambda r: ETAG)(etag_view2)
Example #48
0
class CoverArt(View):

    @method_decorator(last_modified(_last_modified))
    def get(self, request, size, prefix, filename):

        size = int(size)

        target = self.get_thumbnail(size, prefix, filename)
        original = self.get_original(prefix, filename)

        if os.path.exists(target):
            return self.send_file(target)

        if not os.path.exists(original):
            raise Http404('Cover Art not available' + original)

        target_dir = self.get_dir(target)

        try:
            im = Image.open(original)
            if im.mode not in ('RGB', 'RGBA'):
                im = im.convert('RGB')
        except IOError:
            raise Http404('Cannot open cover file')

        try:
            im.thumbnail((size, size), Image.ANTIALIAS)
            resized = im
        except (struct.error, IOError, IndexError) as ex:
            # raised when trying to read an interlaced PNG;
            logger.warn('Could not create thumbnail: %s', str(ex))

            # we use the original instead
            return self.send_file(original)

        # If it's a RGBA image, composite it onto a white background for JPEG
        if resized.mode == 'RGBA':
            background = Image.new('RGB', resized.size)
            draw = ImageDraw.Draw(background)
            draw.rectangle((-1, -1, resized.size[0]+1, resized.size[1]+1),
                           fill=(255, 255, 255))
            del draw
            resized = Image.composite(resized, background, resized)

        sio = io.BytesIO()

        try:
            resized.save(sio, 'JPEG', optimize=True, progression=True,
                         quality=80)
        except IOError as ex:
            return self.send_file(original)

        s = sio.getvalue()

        fp = open(target, 'wb')
        fp.write(s)
        fp.close()

        return self.send_file(target)

    # the length of the prefix is defined here and in web/urls.py
    @staticmethod
    def get_prefix(filename):
        return filename[:3]

    @staticmethod
    def get_thumbnail(size, prefix, filename):
        return os.path.join(LOGO_DIR, str(size), prefix, filename)

    @staticmethod
    def get_existing_thumbnails(prefix, filename):
        files = glob(os.path.join(LOGO_DIR, '*', prefix, filename))
        return [f for f in files if 'original' not in f]

    @staticmethod
    def get_original(prefix, filename):
        return os.path.join(LOGO_DIR, 'original', prefix, filename)

    @staticmethod
    def get_dir(filename):
        path = os.path.dirname(filename)
        try:
            os.makedirs(path)

        except OSError as ose:
            if ose.errno != errno.EEXIST:
                raise

        return path

    def send_file(self, filename):
        try:
            f = open(filename, 'rb')
        except IOError:
            return HttpResponseNotFound()

        resp = HttpResponse(content_type='image/jpeg')
        resp.status_code = 200
        resp.write(f.read())
        return resp
Example #49
0

admin.autodiscover()
admin.site.login_form = AdminAuthenticationForm


urlpatterns = [
    url(r'^', include('misago.urls', namespace='misago')),

    # Javascript translations
    url(
        r'^django-i18n.js$',
        last_modified(lambda req, **kw: timezone.now())(
            cache_page(86400 * 2, key_prefix='misagojsi18n')(
                JavaScriptCatalog.as_view(
                    packages=['misago'],
                ),
            ),
        ),
        name='django-i18n',
    ),

    # Uncomment next line if you plan to use Django admin for 3rd party apps
    #url(r'^django-admin/', admin.site.urls),
]


# If debug mode is enabled, include debug toolbar
if settings.DEBUG:
    import debug_toolbar
    urlpatterns += [
Example #50
0
            "properties": data_dict["properties_cache__data"],
            "where": where,
            "permalink": get_site_url(reverse("exhibit_display",
                                              kwargs={'owner': owner,
                                                      'slug': slug})),
            "canvas": canvas_html})
        response['Content-Type'] = "application/javascript"
        response['Cache-Control'] = "no-cache, must-revalidate, public"
        return response

def lmfunc(r, owner, slug):
    ex = get_published_exhibit(r, owner, slug)
    if ex.modified > ex.dataset.modified:
        return ex.modified
    return ex.dataset.modified
embedded_exhibit_view = last_modified(lmfunc)(EmbeddedExhibitView.as_view())

# Exhibit Profile Views

class StockExhibitProfileJSONView(View):
    """Generate the default profile description of an exhibit for a particular dataset and canvas
    """
    def get(self, request, *args, **kwargs):
        owner = kwargs["owner"]
        slug = kwargs["slug"]

        ds = get_object_or_404(models.Dataset, owner__username=owner, slug=slug)
        user = self.request.user

        if not user.has_perm("dataset.can_view", ds):
            raise Http404