示例#1
0
    def test_derivative_permissions(self):
        Media.objects.filter(record=self.record).delete()
        media = Media.objects.create(record=self.record, name='tiff', mimetype='image/tiff', storage=self.storage)
        with open(os.path.join(os.path.dirname(__file__), 'test_data', 'dcmetro.tif'), 'rb') as f:
            media.save_file('dcmetro.tif', f)

        user1 = User.objects.create(username='******')
        user2 = User.objects.create(username='******')

        AccessControl.objects.create(content_object=self.collection, user=user1, read=True)
        AccessControl.objects.create(content_object=self.collection, user=user2, read=True)

        AccessControl.objects.create(content_object=self.storage, user=user1, read=True)
        AccessControl.objects.create(content_object=self.storage, user=user2, read=True,
                                     restrictions=dict(width=200, height=200))

        result1 = get_image_for_record(self.record, width=400, height=400, user=user1)
        result2 = get_image_for_record(self.record, width=400, height=400, user=user2)

        self.assertEqual(400, Image.open(result1).size[0])
        self.assertEqual(200, Image.open(result2).size[0])

        result3 = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(result2, result3)

        media.delete()
示例#2
0
    def test_derivative_permissions(self):
        no_signals()
        Media.objects.filter(record=self.record).delete()
        media = Media.objects.create(record=self.record, name='tiff', mimetype='image/tiff', storage=self.storage)
        with open(os.path.join(os.path.dirname(__file__), 'test_data', 'dcmetro.tif'), 'rb') as f:
            media.save_file('dcmetro.tif', f)

        user1 = User.objects.create(username='******')
        user2 = User.objects.create(username='******')

        AccessControl.objects.create(content_object=self.collection, user=user1, read=True)
        AccessControl.objects.create(content_object=self.collection, user=user2, read=True)

        AccessControl.objects.create(content_object=self.storage, user=user1, read=True)
        AccessControl.objects.create(content_object=self.storage, user=user2, read=True,
                                     restrictions=dict(width=200, height=200))

        result1 = get_image_for_record(self.record, width=400, height=400, user=user1)
        result2 = get_image_for_record(self.record, width=400, height=400, user=user2)

        self.assertEqual(400, Image.open(result1).size[0])
        self.assertEqual(200, Image.open(result2).size[0])

        result3 = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(result2, result3)

        media.delete()
示例#3
0
    def view(self, request):

        def filename(title):
            return re.sub('[^A-Za-z0-9_. ]+', '-', title)[:32]

        def write(output, image, index, title, prefix=None):
            if image:
                output.write(image, ('%s%s %s%s' % (
                    os.path.join(prefix, '') if prefix else '',
                    str(index + 1).zfill(4),
                    filename(title),
                    os.path.splitext(image)[1])
                  ).encode('ascii', 'replace'))

        presentation = self.obj
        passwords = request.session.get('passwords', dict())
        response = HttpResponse(mimetype='application/zip')
        response['Content-Disposition'] = 'attachment; filename=%s.zip' % filename(presentation.title)
        items = presentation.items.filter(hidden=False)
        memory = StringIO()
        output = zipfile.ZipFile(memory, 'w')

        for index, item in enumerate(items):
            write(output, get_image_for_record(item.record, self.user, passwords=passwords),
                  index, item.record.title)
            write(output, get_image_for_record(item.record, self.user, 100, 100, passwords),
                  index, item.record.title, 'thumb')

        output.close()
        response.write(memory.getvalue())
        return response
示例#4
0
    def view(self, request):

        def filename(title):
            return re.sub('[^A-Za-z0-9_. ]+', '-', title)[:32]

        def write(output, image, index, title, prefix=None):
            if image:
                output.write(image, ('%s%s %s%s' % (
                    os.path.join(prefix, '') if prefix else '',
                    str(index + 1).zfill(4),
                    filename(title or 'Slide %s' % (index + 1)),
                    os.path.splitext(image)[1])
                                     ).encode('ascii', 'replace'))

        def metadata_file(tempfile, record):
            t = Template("{% load data %}{% metadata record %}")
            c = Context({'record': record, 'request': request})
            tempfile.write(smart_str(t.render(c)))
            tempfile.flush()
            return tempfile.name

        presentation = self.obj
        passwords = request.session.get('passwords', dict())
        items = presentation.items.filter(hidden=False)

        tempfile = NamedTemporaryFile(suffix='.zip')
        output = zipfile.ZipFile(tempfile, 'w')

        tempjsonfile = NamedTemporaryFile(suffix='.json')
        metadata = presentation_detail(request, presentation.id)
        tempjsonfile.write(metadata.content)
        tempjsonfile.flush()
        output.write(tempjsonfile.name, os.path.join('metadata', 'metadata.json'))

        for index, item in enumerate(items):
            write(output, get_image_for_record(item.record, self.user, passwords=passwords),
                  index, item.record.title)
            write(output, get_image_for_record(item.record, self.user, 100, 100, passwords),
                  index, item.record.title, 'thumb')

            tempmetadatafile = NamedTemporaryFile(suffix='.html')
            write(output, metadata_file(tempmetadatafile, item.record),
                  index, item.record.title, 'metadata')

        output.close()
        tempfile.flush()
        tempfile.seek(0)

        wrapper = FileWrapper(tempfile)
        response = HttpResponse(wrapper, content_type='application/zip')
        response['Content-Disposition'] = 'attachment; filename=%s.zip' % filename(presentation.title)
        response['Content-Length'] = os.path.getsize(tempfile.name)
        return response
示例#5
0
    def view(self, request):

        def filename(title):
            return re.sub('[^A-Za-z0-9_. ]+', '-', title)[:32]

        def write(output, image, index, title, prefix=None):
            if image:
                output.write(image, ('%s%s %s%s' % (
                    os.path.join(prefix, '') if prefix else '',
                    str(index + 1).zfill(4),
                    filename(title),
                    os.path.splitext(image)[1])
                  ).encode('ascii', 'replace'))

        def metadata_file(tempfile, record):
            t = Template("{% load data %}{% metadata record %}")
            c = Context({'record': record, 'request': request})
            tempfile.write(t.render(c))
            tempfile.flush()
            return tempfile.name

        presentation = self.obj
        passwords = request.session.get('passwords', dict())
        items = presentation.items.filter(hidden=False)

        tempfile = NamedTemporaryFile(suffix='.zip')
        output = zipfile.ZipFile(tempfile, 'w')

        tempjsonfile = NamedTemporaryFile(suffix='.json')
        metadata = presentation_detail(request, presentation.id)
        tempjsonfile.write(metadata.content)
        tempjsonfile.flush()
        output.write(tempjsonfile.name, os.path.join('metadata', 'metadata.json'))

        for index, item in enumerate(items):
            write(output, get_image_for_record(item.record, self.user, passwords=passwords),
                  index, item.record.title)
            write(output, get_image_for_record(item.record, self.user, 100, 100, passwords),
                  index, item.record.title, 'thumb')

            tempmetadatafile = NamedTemporaryFile(suffix='.html')
            write(output, metadata_file(tempmetadatafile, item.record),
                  index, item.record.title, 'metadata')

        output.close()
        tempfile.flush()
        tempfile.seek(0)

        wrapper = FileWrapper(tempfile)
        response = HttpResponse(wrapper, mimetype='application/zip')
        response['Content-Disposition'] = 'attachment; filename=%s.zip' % filename(presentation.title)
        response['Content-Length'] = os.path.getsize(tempfile.name)
        return response
示例#6
0
文件: views.py 项目: knabar/fynbos
def retrieve_image(request, recordid, record, width=None, height=None):

    passwords = request.session.get('passwords', dict())
    force_reprocess = request.GET.has_key('reprocess')

    path = get_image_for_record(
        recordid, request.user, int(width or 100000), int(height or 100000), passwords,
        force_reprocess=force_reprocess)
    if not path:
        logging.error("get_image_for_record failed for record.id %s" % recordid)
        raise Http404()

    Activity.objects.create(event='media-download-image',
                            request=request,
                            content_object=Record.objects.get(id=recordid),
                            data=dict(width=width, height=height))
    try:
        response = HttpResponse(content=file(path, 'rb').read(), mimetype='image/jpeg')
        if request.GET.has_key('forcedl'):
            # if filename was used for record stub, remove extension here to
            # prevent duplication
            if record.endswith('jpg'):
                record = record[:-3]
            response["Content-Disposition"] = "attachment; filename=%s.jpg" % record
        return response
    except IOError:
        logging.error("IOError: %s" % path)
        raise Http404()
示例#7
0
def retrieve_image(request, recordid, record, width=None, height=None):

    passwords = request.session.get('passwords', dict())
    force_reprocess = 'reprocess' in request.GET

    path = get_image_for_record(recordid,
                                request.user,
                                int(width or 100000),
                                int(height or 100000),
                                passwords,
                                force_reprocess=force_reprocess)
    if not path:
        logging.error("get_image_for_record failed for record.id %s" %
                      recordid)
        raise Http404()

    Activity.objects.create(event='media-download-image',
                            request=request,
                            content_object=Record.objects.get(id=recordid),
                            data=dict(width=width, height=height))
    try:
        response = HttpResponse(content=file(path, 'rb').read(),
                                content_type='image/jpeg')
        if 'forcedl' in request.GET:
            # if filename was used for record stub, remove extension here to
            # prevent duplication
            if record.endswith('jpg'):
                record = record[:-3]
            response["Content-Disposition"] = \
                "attachment; filename=%s.jpg" % record
        return response
    except IOError:
        logging.error("IOError: %s" % path)
        raise Http404()
示例#8
0
        def drawCard(index, item):
            p.saveState()
            p.translate(0, height / 3 * (2 - index % 3))

            # retrieve record while making sure it's accessible to presentation owner
            record = Record.filter_one_by_access(presentation.owner, item.record.id)

            if record:
                image = get_image_for_record(record, presentation.owner, 800, 800, passwords)
                if image:
                    p.drawImage(image, inch / 2, inch / 2, width=width / 2 - inch, height=height / 3 - inch,
                                preserveAspectRatio=True)
                f = Frame(width / 2 + inch / 2, inch / 2,
                          width=width / 2 - inch, height=height / 3 - inch,
                          leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0)
                data = []
                data.append(getParagraph('%s/%s' % (index + 1, len(items)), styles['SlideNumber']))
                values = item.get_fieldvalues(owner=request.user)
                for value in values:
                    v = value.value if len(value.value) < 100 else value.value[:100] + '...'

                    v = remove_rels_from_a_tags(v)

                    data.append(getParagraph('<b>%s:</b> %s' % (value.resolved_label, v), styles['Data']))
                annotation = item.annotation
                if annotation:
                    data.append(getParagraph('<b>%s:</b> %s' % ('Annotation', annotation), styles['Data']))
                data = filter(None, data)
                f.addFromList(data, p)
                if data:
                    p.setFont('Helvetica', 8)
                    p.setFillColorRGB(0, 0, 0)
                    p.drawRightString(width - inch / 2, inch / 2, '...')

            p.restoreState()
示例#9
0
def retrieve_image(request, recordid, record, width=None, height=None):
    if DEBUG:
        print 'storage/views.py -- retrieve_image'
        print 'record = ' + record
        print 'record_id = ' + recordid
        print 'width = '+ str(width) +' and height = '+str(height)
    passwords = request.session.get('passwords', dict())
    #print 'record image path ' + record.get_absolute_url()
    path = get_image_for_record(recordid, request.user, int(width or 100000), int(height or 100000), passwords)
    if not path:
        #raise Http404()
        if DEBUG:
            print "THUMBNAIL UNAVAILABLE - NO PATH"
        return HttpResponseRedirect(reverse('static', args=('images/thumbnail_unavailable.png',)))

    Activity.objects.create(event='media-download-image',
                            request=request,
                            content_object=Record.objects.get(id=recordid),
                            data=dict(width=width, height=height))
    try:
        response = HttpResponse(content=file(path, 'rb').read(), mimetype='image/jpeg')
        if request.GET.has_key('forcedl'):
            response["Content-Disposition"] = "attachment; filename=%s.jpg" % record
        return response
    except IOError:
        logging.error("IOError: %s" % path)
        #raise Http404()
        print "THUMBNAIL UNAVAILABLE - IO ERROR"
        return HttpResponseRedirect(reverse('static', args=('images/thumbnail_unavailable.png',)))
示例#10
0
def retrieve_iiif_image(request, recordid, record):

    passwords = request.session.get('passwords', dict())
    force_reprocess = 'reprocess' in request.GET

    path = get_image_for_record(
        recordid,
        request.user,
        passwords=passwords,
        force_reprocess=force_reprocess,
        loris_name=True,  # Loris does not deal with spaces in filenames
    )
    if not path:
        logging.error("get_image_for_record failed for record.id %s" %
                      recordid)
        raise Http404()

    record_obj = Record.objects.get(id=recordid)

    Activity.objects.create(event='media-download-image',
                            request=request,
                            content_object=record_obj,
                            data=dict())

    return handle_loris_request(request, path, recordid, record)
示例#11
0
def retrieve_image(request, recordid, record, width=None, height=None):

    passwords = request.session.get('passwords', dict())

    path = get_image_for_record(recordid, request.user, int(width or 100000),
                                int(height or 100000), passwords)
    if not path:
        logging.error("get_image_for_record failed for record.id %s" %
                      recordid)
        raise Http404()

    Activity.objects.create(event='media-download-image',
                            request=request,
                            content_object=Record.objects.get(id=recordid),
                            data=dict(width=width, height=height))
    try:
        response = HttpResponse(content=file(path, 'rb').read(),
                                mimetype='image/jpeg')
        if request.GET.has_key('forcedl'):
            response[
                "Content-Disposition"] = "attachment; filename=%s.jpg" % record
        return response
    except IOError:
        logging.error("IOError: %s" % path)
        raise Http404()
示例#12
0
        def drawCard(index, item):
            p.saveState()
            p.translate(0, height / 3 * (2 - index % 3))

            # retrieve record while making sure it's accessible to presentation owner
            record = Record.filter_one_by_access(presentation.owner, item.record.id)

            if record:
                image = get_image_for_record(record, presentation.owner, 800, 800, passwords)
                if image:
                    p.drawImage(image, inch / 2, inch / 2, width=width / 2 - inch, height=height / 3 - inch,
                                preserveAspectRatio=True)
                f = Frame(width / 2 + inch / 2, inch / 2,
                          width=width / 2 - inch, height = height / 3 - inch,
                          leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0)
                data = []
                data.append(getParagraph('%s/%s' % (index + 1, len(items)), styles['SlideNumber']))
                values = item.get_fieldvalues(owner=request.user)
                for value in values:
                    v = value.value if len(value.value) < 100 else value.value[:100] + '...'
                    data.append(getParagraph('<b>%s:</b> %s' % (value.resolved_label, v), styles['Data']))
                annotation = item.annotation
                if annotation:
                    data.append(getParagraph('<b>%s:</b> %s' % ('Annotation', annotation), styles['Data']))
                data = filter(None, data)
                f.addFromList(data, p)
                if data:
                    p.setFont('Helvetica', 8)
                    p.setFillColorRGB(0, 0, 0)
                    p.drawRightString(width - inch / 2, inch / 2, '...')

            p.restoreState()
示例#13
0
文件: views.py 项目: Blanko2/vic-mdid
def retrieve_image(request, recordid, record, width=None, height=None):
    print 'retrieve_image'

    passwords = request.session.get('passwords', dict())

    path = get_image_for_record(recordid, request.user, int(width or 100000), int(height or 100000), passwords)
    if not path:
        #raise Http404()
        print "THUMBNAIL UNAVAILABLE - NO PATH"
        return HttpResponseRedirect(reverse('static', args=('images/thumbnail_unavailable.png',)))

    Activity.objects.create(event='media-download-image',
                            request=request,
                            content_object=Record.objects.get(id=recordid),
                            data=dict(width=width, height=height))
    try:
        response = HttpResponse(content=file(path, 'rb').read(), mimetype='image/jpeg')
        if request.GET.has_key('forcedl'):
            response["Content-Disposition"] = "attachment; filename=%s.jpg" % record
        return response
    except IOError:
        logging.error("IOError: %s" % path)
        #raise Http404()
        print "THUMBNAIL UNAVAILABLE - IO ERROR"
        return HttpResponseRedirect(reverse('static', args=('images/thumbnail_unavailable.png',)))
示例#14
0
    def test_access_through_presentation(self):
        no_signals()
        Media.objects.filter(record=self.record).delete()
        media = Media.objects.create(record=self.record, name='tiff', mimetype='image/tiff', storage=self.storage)
        with open(os.path.join(os.path.dirname(__file__), 'test_data', 'dcmetro.tif'), 'rb') as f:
            media.save_file('dcmetro.tif', f)

        user1 = User.objects.create(username='******')
        user2 = User.objects.create(username='******')

        AccessControl.objects.create(content_object=self.collection, user=user1, read=True)
        storage_acl = AccessControl.objects.create(content_object=self.storage, user=user1, read=True)

        presentation = Presentation.objects.create(title='test47949074', owner=user1)
        presentation.items.create(record=self.record, order=1)

        # user2 has no access to storage or collection, so should not get result
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(None, result)

        # give access to presentation
        AccessControl.objects.create(content_object=presentation, user=user2, read=True)

        # user2 has no access to storage yet, so still should not get result
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(None, result)

        # give user2 access to storage
        user2_storage_acl = AccessControl.objects.create(content_object=self.storage, user=user2, read=True)

        # now user2 should get the image
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(400, Image.open(result).size[0])

        # limit user2 image size
        user2_storage_acl.restrictions = dict(width=200, height=200)
        user2_storage_acl.save()

        # we should now get a smaller image
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(200, Image.open(result).size[0])

        # password protect the presentation
        presentation.password='******'
        presentation.save()

        # user2 has not provided presentation password, so should not get result
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(None, result)

        # with presentation password, image should be returned
        result = get_image_for_record(self.record, width=400, height=400, user=user2,
                                      passwords={presentation.id: 'secret'})
        self.assertEqual(200, Image.open(result).size[0])
示例#15
0
    def test_access_through_presentation(self):
        Media.objects.filter(record=self.record).delete()
        media = Media.objects.create(record=self.record, name='tiff', mimetype='image/tiff', storage=self.storage)
        with open(os.path.join(os.path.dirname(__file__), 'test_data', 'dcmetro.tif'), 'rb') as f:
            media.save_file('dcmetro.tif', f)

        user1 = User.objects.create(username='******')
        user2 = User.objects.create(username='******')

        AccessControl.objects.create(content_object=self.collection, user=user1, read=True)
        storage_acl = AccessControl.objects.create(content_object=self.storage, user=user1, read=True)

        presentation = Presentation.objects.create(title='test47949074', owner=user1)
        presentation.items.create(record=self.record, order=1)

        # user2 has no access to storage or collection, so should not get result
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(None, result)

        # give access to presentation
        AccessControl.objects.create(content_object=presentation, user=user2, read=True)

        # user2 has no access to storage yet, so still should not get result
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(None, result)

        # give user2 access to storage
        user2_storage_acl = AccessControl.objects.create(content_object=self.storage, user=user2, read=True)

        # now user2 should get the image
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(400, Image.open(result).size[0])

        # limit user2 image size
        user2_storage_acl.restrictions = dict(width=200, height=200)
        user2_storage_acl.save()

        # we should now get a smaller image
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(200, Image.open(result).size[0])

        # password protect the presentation
        presentation.password='******'
        presentation.save()

        # user2 has not provided presentation password, so should not get result
        result = get_image_for_record(self.record, width=400, height=400, user=user2)
        self.assertEqual(None, result)

        # with presentation password, image should be returned
        result = get_image_for_record(self.record, width=400, height=400, user=user2,
                                      passwords={presentation.id: 'secret'})
        self.assertEqual(200, Image.open(result).size[0])
示例#16
0
def retrieve_image(request, recordid, record, width=None, height=None):

    passwords = request.session.get('passwords', dict())

    path = get_image_for_record(recordid, request.user, int(width or 100000), int(height or 100000), passwords)
    if not path:
        raise Http404()

    Activity.objects.create(event='media-download-image',
                            request=request,
                            content_object=Record.objects.get(id=recordid),
                            data=dict(width=width, height=height))
    try:
        response = HttpResponse(content=file(path, 'rb').read(), mimetype='image/jpeg')
        if request.GET.has_key('forcedl'):
            response["Content-Disposition"] = "attachment; filename=%s.jpg" % record
        return response
    except IOError:
        logging.error("IOError: %s" % path)
        raise Http404()
示例#17
0
    def view(self, request):
        presentation = self.obj

        passwords = request.session.get('passwords', dict())

        response = HttpResponse(mimetype='application/pdf')

        pagesize = getattr(pagesizes, settings.PDF_PAGESIZE)
        width, height = pagesize

        class DocTemplate(BaseDocTemplate):
            def afterPage(self):
                self.handle_nextPageTemplate('Later')

        def column_frame(left):
            return Frame(left,
                         inch / 2,
                         width=width / 2 - 0.75 * inch,
                         height=height - inch,
                         leftPadding=0,
                         bottomPadding=0,
                         rightPadding=0,
                         topPadding=0,
                         showBoundary=False)

        def prepare_first_page(canvas, document):
            p1 = Paragraph(presentation.title, styles['Heading'])
            p2 = Paragraph(presentation.owner.get_full_name(),
                           styles['SubHeading'])
            avail_width = width - inch
            avail_height = height - inch
            w1, h1 = p1.wrap(avail_width, avail_height)
            w2, h2 = p2.wrap(avail_width, avail_height)
            f = Frame(inch / 2,
                      inch / 2,
                      width - inch,
                      height - inch,
                      leftPadding=0,
                      bottomPadding=0,
                      rightPadding=0,
                      topPadding=0)
            f.addFromList([p1, p2], canvas)

            document.pageTemplate.frames[0].height -= h1 + h2 + inch / 2
            document.pageTemplate.frames[1].height -= h1 + h2 + inch / 2

            canvas.saveState()
            canvas.setStrokeColorRGB(0, 0, 0)
            canvas.line(width / 2, inch / 2, width / 2,
                        height - inch - h1 - h2)
            canvas.restoreState()

        def prepare_later_page(canvas, document):
            canvas.saveState()
            canvas.setStrokeColorRGB(0, 0, 0)
            canvas.line(width / 2, inch / 2, width / 2, height - inch / 2)
            canvas.restoreState()

        def getStyleSheet():
            stylesheet = StyleSheet1()
            stylesheet.add(
                ParagraphStyle(name='Normal',
                               fontName='Times-Roman',
                               fontSize=8,
                               leading=10,
                               spaceAfter=18))
            stylesheet.add(
                ParagraphStyle(name='SlideNumber',
                               parent=stylesheet['Normal'],
                               alignment=TA_RIGHT,
                               fontSize=6,
                               leading=8,
                               rightIndent=3,
                               spaceAfter=0))
            stylesheet.add(
                ParagraphStyle(name='Heading',
                               parent=stylesheet['Normal'],
                               fontSize=20,
                               leading=24,
                               alignment=TA_CENTER,
                               spaceAfter=0))
            stylesheet.add(
                ParagraphStyle(name='SubHeading',
                               parent=stylesheet['Normal'],
                               fontSize=16,
                               leading=20,
                               alignment=TA_CENTER))
            return stylesheet

        styles = getStyleSheet()

        items = presentation.items.filter(hidden=False)

        content = []

        for index, item in enumerate(items):
            text = []
            values = item.get_fieldvalues(owner=request.user)
            for value in values:
                text.append('<b>%s</b>: %s<br />' %
                            (value.resolved_label, value.value))
            annotation = item.annotation
            if annotation:
                text.append('<b>%s</b>: %s<br />' % ('Annotation', annotation))
            try:
                p = Paragraph(''.join(text), styles['Normal'])
            except (AttributeError, KeyError, IndexError):
                # this sometimes triggers an error in reportlab
                p = None
            if p:
                image = get_image_for_record(item.record, presentation.owner,
                                             100, 100, passwords)
                if image:
                    try:
                        i = flowables.Image(image,
                                            kind='proportional',
                                            width=1 * inch,
                                            height=1 * inch)
                        p = flowables.ParagraphAndImage(p, i)
                    except IOError:
                        pass
                content.append(
                    flowables.KeepTogether([
                        Paragraph('%s/%s' % (index + 1, len(items)),
                                  styles['SlideNumber']), p
                    ]))

        first_template = PageTemplate(id='First',
                                      frames=[
                                          column_frame(inch / 2),
                                          column_frame(width / 2 + 0.25 * inch)
                                      ],
                                      pagesize=pagesize,
                                      onPage=prepare_first_page)
        later_template = PageTemplate(id='Later',
                                      frames=[
                                          column_frame(inch / 2),
                                          column_frame(width / 2 + 0.25 * inch)
                                      ],
                                      pagesize=pagesize,
                                      onPage=prepare_later_page)

        doc = DocTemplate(response)
        doc.addPageTemplates([first_template, later_template])
        doc.build(content)

        return response
示例#18
0
    def _process_slides(self, outfile):
        for n in range(2, len(self.items) + 2):
            item = self.items[n - 2]

            x = xml.dom.minidom.parseString(self.slide_template)
            xr = xml.dom.minidom.parseString(self.slide_rel_template)
            xn = xml.dom.minidom.parseString(self.slide_notes_template)
            xnr = xml.dom.minidom.parseString(self.slide_notes_rel_template)
            record = item.record

            # insert notes
            fieldvalues = list(item.get_fieldvalues())
            if fieldvalues:
                fieldvalues[0]._subitem = False
            for i in range(1, len(fieldvalues)):
                fieldvalues[i]._subitem = (fieldvalues[i].field == fieldvalues[i - 1].field and
                                          fieldvalues[i].group == fieldvalues[i - 1].group)

            body = xn.getElementsByTagName('p:txBody').item(0)

            def appendText(text):
                ap1 = xn.createElement('a:p')
                ar = xn.createElement('a:r')
                arPr = xn.createElement('a:rPr')
                arPr.setAttribute('dirty','0')
                arPr.setAttribute('lang','en-US')
                arPr.setAttribute('smtClean','0')
                at = xn.createElement('a:t')
                txt = xn.createTextNode(text)
                at.appendChild(txt)
                ar.appendChild(arPr)
                ar.appendChild(at)
                ap1.appendChild(ar)
                body.appendChild(ap1)

            for value in fieldvalues:
                appendText('%s%s: %s' % (
                      value._subitem and 'sub' or '',
                      value.resolved_label,
                      value.value or ''))

            annotation = item.annotation
            if annotation:
                appendText('Annotation: %s' % annotation)

            # update the slide number in notes
            e = filter(lambda e: e.getAttribute('type') == 'slidenum', xn.getElementsByTagName('a:fld'))[0]
            e.getElementsByTagName('a:t').item(0).firstChild.nodeValue = n

            # insert title
            for e in x.getElementsByTagName('a:t'):
                t = e.firstChild.nodeValue
                if t == 'title':
                    t = item.title or ''
                e.firstChild.nodeValue = t
            # insert image if available
            image = get_image_for_record(record, self.user, 800, 600)
            if image:
                # add image to outfile
                with file(image, 'rb') as f:
                    content = f.read()
                name = 'image%s.jpg' % n
                self.additional_content_types.setdefault('image/jpeg;jpg', None)
                outfile.writestr('ppt/media/' + name, content)

                # find image placeholder
                e = filter(lambda e: e.getAttribute('descr') == 'image', x.getElementsByTagName('p:cNvPr'))[0]
                e = e.parentNode.parentNode
                embedId = e.getElementsByTagName('a:blip')[0].getAttribute('r:embed')

                try:
                    width, height = Image.open(image).size
                except IOError:
                    width, height = None, None
                if width and height:
                    offset = e.getElementsByTagName('a:off')[0]
                    extent = e.getElementsByTagName('a:ext')[0]
                    px = int(offset.getAttribute('x'))
                    py = int(offset.getAttribute('y'))
                    pw = int(extent.getAttribute('cx'))
                    ph = int(extent.getAttribute('cy'))

                    imageratio = width * 1.0 / height
                    ratio = pw * 1.0 / ph

                    if imageratio > ratio:
                        new_h = height * pw / width
                        new_w = pw
                        new_x = px
                        new_y = py + (ph - new_h) / 2
                    else:
                        new_h = ph
                        new_w = width * ph / height
                        new_x = px + (pw - new_w) / 2
                        new_y = py

                    offset.setAttribute('x', str(new_x))
                    offset.setAttribute('y', str(new_y))
                    extent.setAttribute('cx', str(new_w))
                    extent.setAttribute('cy', str(new_h))

                    # add image to slide relation
                    rel = filter(lambda e: e.getAttribute('Id') == embedId, xr.getElementsByTagName('Relationship'))[0]
                    self.placeholder_image = 'ppt' + rel.getAttribute('Target')[2:]
                    rel.setAttribute('Target', '../media/' + name)

                    # add notes to slide relation
                    rel2 = filter(lambda e: e.getAttribute('Type') ==
                                  "http://schemas.openxmlformats.org/officeDocument/2006/relationships/notesSlide",
                                  xr.getElementsByTagName('Relationship'))[0]
                    rel2.setAttribute('Target', '../notesSlides/notesSlide%s.xml' % n)

                    # add slide to notes relation
                    rel3 = filter(lambda e: e.getAttribute('Type') ==
                                  "http://schemas.openxmlformats.org/officeDocument/2006/relationships/slide",
                                  xnr.getElementsByTagName('Relationship'))[0]
                    rel3.setAttribute('Target', '../slides/slide%s.xml' % n)
            else:
                self.remove_placeholder_image = False

            outfile.writestr('ppt/slides/slide%s.xml' % n, standalone(x.toxml(encoding="UTF-8")))
            outfile.writestr('ppt/slides/_rels/slide%s.xml.rels' % n, standalone(xr.toxml(encoding="UTF-8")))
            outfile.writestr('ppt/notesSlides/notesSlide%s.xml' % n, standalone(xn.toxml(encoding="UTF-8")))
            outfile.writestr('ppt/notesSlides/_rels/notesSlide%s.xml.rels' % n, standalone(xnr.toxml(encoding="UTF-8")))
示例#19
0
    def view(self, request, id, name):
        return_url = request.GET.get('next', reverse('presentation-browse'))
        presentation = Presentation.get_by_id_for_request(id, request)
        if not presentation:
            if not request.user.is_authenticated():
                return HttpResponseRedirect(reverse('login') + '?next=' + request.get_full_path())
            else:
                return HttpResponseRedirect(return_url)

        passwords = request.session.get('passwords', dict())

        response = HttpResponse(mimetype='application/pdf')

        pagesize = getattr(pagesizes, settings.PDF_PAGESIZE)
        width, height = pagesize

        class DocTemplate(BaseDocTemplate):
            def afterPage(self):
                self.handle_nextPageTemplate('Later')

        def column_frame(left):
            return Frame(left, inch / 2,
                           width=width / 2 - 0.75 * inch, height = height - inch,
                          leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0, showBoundary=False)

        def prepare_first_page(canvas, document):
            p1 = Paragraph(presentation.title, styles['Heading'])
            p2 = Paragraph(presentation.owner.get_full_name(), styles['SubHeading'])
            avail_width = width - inch
            avail_height = height - inch
            w1, h1 = p1.wrap(avail_width, avail_height)
            w2, h2 = p2.wrap(avail_width, avail_height)
            f = Frame(inch / 2, inch / 2, width - inch, height - inch,
                      leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0)
            f.addFromList([p1, p2], canvas)

            document.pageTemplate.frames[0].height -= h1 + h2 + inch / 2
            document.pageTemplate.frames[1].height -= h1 + h2 + inch / 2

            canvas.saveState()
            canvas.setStrokeColorRGB(0, 0, 0)
            canvas.line(width / 2, inch / 2, width / 2, height - inch - h1 - h2)
            canvas.restoreState()

        def prepare_later_page(canvas, document):
            canvas.saveState()
            canvas.setStrokeColorRGB(0, 0, 0)
            canvas.line(width / 2, inch / 2, width / 2, height - inch / 2)
            canvas.restoreState()


        styles = getStyleSheet()

        items = presentation.items.filter(hidden=False)

        content = []

        for index, item in enumerate(items):
            text = []
            values = item.get_fieldvalues(owner=request.user)
            for value in values:
                text.append('<b>%s</b>: %s<br />' % (value.resolved_label, value.value))
            annotation = item.annotation
            if annotation:
                text.append('<b>%s</b>: %s<br />' % ('Annotation', annotation))
            try:
                p = Paragraph(''.join(text), styles['Normal'])
            except (AttributeError, KeyError, IndexError):
                # this sometimes triggers an error in reportlab
                p = None
            if p:
                image = get_image_for_record(item.record, presentation.owner, 100, 100, passwords)
                if image:
                    try:
                        i = flowables.Image(image, kind='proportional',
                                            width=1 * inch, height=1 * inch)
                        p = flowables.ParagraphAndImage(p, i)
                    except IOError:
                        pass
                content.append(flowables.KeepTogether(
                    [Paragraph('%s/%s' % (index + 1, len(items)), styles['SlideNumber']), p]))

        first_template = PageTemplate(id='First',
                                      frames=[column_frame(inch / 2), column_frame(width / 2 + 0.25 * inch)],
                                      pagesize=pagesize,
                                      onPage=prepare_first_page)
        later_template = PageTemplate(id='Later',
                                      frames=[column_frame(inch / 2), column_frame(width / 2 + 0.25 * inch)],
                                      pagesize=pagesize,
                                      onPage=prepare_later_page)

        doc = DocTemplate(response)
        doc.addPageTemplates([first_template, later_template])
        doc.build(content)

        return response
示例#20
0
    def _process_slides(self, outfile):
        for n in range(2, len(self.items) + 2):
            item = self.items[n - 2]

            x = xml.dom.minidom.parseString(self.slide_template)
            xr = xml.dom.minidom.parseString(self.slide_rel_template)
            xn = xml.dom.minidom.parseString(self.slide_notes_template)
            xnr = xml.dom.minidom.parseString(self.slide_notes_rel_template)
            record = item.record

            # insert notes
            fieldvalues = list(item.get_fieldvalues())
            if fieldvalues:
                fieldvalues[0]._subitem = False
            for i in range(1, len(fieldvalues)):
                fieldvalues[i]._subitem = (
                    fieldvalues[i].field == fieldvalues[i - 1].field
                    and fieldvalues[i].group == fieldvalues[i - 1].group)

            body = xn.getElementsByTagName('p:txBody').item(0)

            def append_text(text):
                ap1 = xn.createElement('a:p')
                ar = xn.createElement('a:r')
                ar_pr = xn.createElement('a:rPr')
                ar_pr.setAttribute('dirty', '0')
                ar_pr.setAttribute('lang', 'en-US')
                ar_pr.setAttribute('smtClean', '0')
                at = xn.createElement('a:t')
                txt = xn.createTextNode(text)
                at.appendChild(txt)
                ar.appendChild(ar_pr)
                ar.appendChild(at)
                ap1.appendChild(ar)
                body.appendChild(ap1)

            for value in fieldvalues:
                append_text('%s%s: %s' %
                            (value._subitem and 'sub'
                             or '', value.resolved_label, value.value or ''))

            annotation = item.annotation
            if annotation:
                append_text('Annotation: %s' % annotation)

            # update the slide number in notes
            e = filter(lambda e: e.getAttribute('type') == 'slidenum',
                       xn.getElementsByTagName('a:fld'))[0]
            e.getElementsByTagName('a:t').item(0).firstChild.nodeValue = n

            # insert title
            for e in x.getElementsByTagName('a:t'):
                t = e.firstChild.nodeValue
                if t == 'title':
                    t = item.title or ''
                e.firstChild.nodeValue = t
            # insert image if available
            try:
                image = get_image_for_record(
                    record, self.user, getattr(settings, 'PPTEXPORT_WIDTH',
                                               800),
                    getattr(settings, 'PPTEXPORT_HEIGHT', 600))
            except:
                image = None
            if image and os.path.isfile(image):
                # add image to outfile
                with file(image, 'rb') as f:
                    content = f.read()
                name = 'image%s.jpg' % n
                self.additional_content_types.setdefault(
                    'image/jpeg;jpg', None)
                outfile.writestr('ppt/media/' + name, content)

                # find image placeholder
                e = filter(lambda e: e.getAttribute('descr') == 'image',
                           x.getElementsByTagName('p:cNvPr'))[0]
                e = e.parentNode.parentNode
                embed_id = e.getElementsByTagName('a:blip')[0].getAttribute(
                    'r:embed')

                try:
                    width, height = Image.open(image).size
                except IOError:
                    width, height = None, None
                if width and height:
                    offset = e.getElementsByTagName('a:off')[0]
                    extent = e.getElementsByTagName('a:ext')[0]
                    px = int(offset.getAttribute('x'))
                    py = int(offset.getAttribute('y'))
                    pw = int(extent.getAttribute('cx'))
                    ph = int(extent.getAttribute('cy'))

                    imageratio = width * 1.0 / height
                    ratio = pw * 1.0 / ph

                    if imageratio > ratio:
                        new_h = height * pw / width
                        new_w = pw
                        new_x = px
                        new_y = py + (ph - new_h) / 2
                    else:
                        new_h = ph
                        new_w = width * ph / height
                        new_x = px + (pw - new_w) / 2
                        new_y = py

                    offset.setAttribute('x', str(new_x))
                    offset.setAttribute('y', str(new_y))
                    extent.setAttribute('cx', str(new_w))
                    extent.setAttribute('cy', str(new_h))

                    # add image to slide relation
                    rel = filter(lambda e: e.getAttribute('Id') == embed_id,
                                 xr.getElementsByTagName('Relationship'))[0]
                    self.placeholder_image = 'ppt' + rel.getAttribute(
                        'Target')[2:]
                    rel.setAttribute('Target', '../media/' + name)

                    # add notes to slide relation
                    rel2 = filter(
                        lambda e: e.getAttribute('Type') ==
                        "http://schemas.openxmlformats.org/officeDocument/"
                        "2006/relationships/notesSlide",
                        xr.getElementsByTagName('Relationship'))[0]
                    rel2.setAttribute('Target',
                                      '../notesSlides/notesSlide%s.xml' % n)

                    # add slide to notes relation
                    rel3 = filter(
                        lambda e: e.getAttribute('Type') ==
                        "http://schemas.openxmlformats.org/officeDocument/"
                        "2006/relationships/slide",
                        xnr.getElementsByTagName('Relationship'))[0]
                    rel3.setAttribute('Target', '../slides/slide%s.xml' % n)
            else:
                self.remove_placeholder_image = False

            outfile.writestr('ppt/slides/slide%s.xml' % n,
                             standalone(x.toxml(encoding="UTF-8")))
            outfile.writestr('ppt/slides/_rels/slide%s.xml.rels' % n,
                             standalone(xr.toxml(encoding="UTF-8")))
            outfile.writestr('ppt/notesSlides/notesSlide%s.xml' % n,
                             standalone(xn.toxml(encoding="UTF-8")))
            outfile.writestr('ppt/notesSlides/_rels/notesSlide%s.xml.rels' % n,
                             standalone(xnr.toxml(encoding="UTF-8")))
示例#21
0
    def view(self, request):
        def filename(title):
            return re.sub('[^A-Za-z0-9_. ]+', '-', title)[:32]

        presentation = self.obj
        passwords = request.session.get('passwords', dict())
        items = presentation.items.filter(hidden=False)

        tempfile = NamedTemporaryFile(suffix='.zip')
        output = zipfile.ZipFile(tempfile, 'w')

        template_name = getattr(settings, 'PRESENTATION_VIEWER_TEMPLATE',
                                'presentation_viewer.html')
        page = loader.render_to_string(
            template_name, {
                'presentation': self.obj,
                'return_url': '/exit',
                'manifest_url': '/presentation/manifest.json',
            })

        manifest = raw_manifest(request,
                                self.obj.id,
                                self.obj.name,
                                offline=True)

        output.writestr('presentation/index.html', page)
        output.writestr('presentation/manifest.json', json.dumps(manifest))

        for static_file in STATIC_FILES:
            path = finders.find(static_file)
            if path:
                output.write(path, 'static/' + static_file)

        package_files_dir = os.path.join(os.path.dirname(__file__),
                                         'mirador_package')
        for root, dirs, files in os.walk(package_files_dir):
            for f in files:
                path = os.path.join(root, f)
                output.write(path, os.path.relpath(path, package_files_dir))

        for item in items:
            image = get_image_for_record(item.record,
                                         self.user,
                                         passwords=passwords)
            outpath = item.record.get_image_url(
                force_reprocess=False,
                handler='storage-retrieve-iiif-image',
            )
            if image:
                output.write(image, outpath)

            image = get_image_for_record(item.record,
                                         self.user,
                                         100,
                                         100,
                                         passwords=passwords)
            if image:
                output.write(
                    image,
                    'thumbs' + outpath,
                )

        output.writestr(
            reverse('presentation-blank-slide',
                    kwargs=dict(extra='')).strip('/'),
            transparent_png(request, None).content)
        output.writestr(
            reverse('presentation-missing-slide',
                    kwargs=dict(extra='')).strip('/'),
            missing_png(request, None).content)

        output.close()
        tempfile.flush()
        tempfile.seek(0)

        wrapper = FileWrapper(tempfile)
        response = HttpResponse(wrapper, content_type='application/zip')
        response['Content-Disposition'] = \
            'attachment; filename=%s.zip' % filename(presentation.title)
        response['Content-Length'] = os.path.getsize(tempfile.name)
        return response
示例#22
0
    def view(self, request):
        presentation = self.obj

        passwords = request.session.get('passwords', dict())

        response = HttpResponse(content_type='application/pdf')

        pagesize = getattr(pagesizes, settings.PDF_PAGESIZE)
        width, height = pagesize

        class DocTemplate(BaseDocTemplate):
            def afterPage(self):
                self.handle_nextPageTemplate('Later')

        def column_frame(left):
            return Frame(left, inch / 2,
                         width=width / 2 - 0.75 * inch, height=height - inch,
                         leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0, showBoundary=False)

        def prepare_first_page(canvas, document):
            p1 = Paragraph(presentation.title, styles['Heading'])
            p2 = Paragraph(presentation.owner.get_full_name(), styles['SubHeading'])
            avail_width = width - inch
            # TODO: determine if the complaint about height being undeclared is just pycharm or if its a problem
            # if it is possibly a problem "it's better to be explicit" so refactor
            avail_height = height - inch
            w1, h1 = p1.wrap(avail_width, avail_height)
            w2, h2 = p2.wrap(avail_width, avail_height)
            f = Frame(inch / 2, inch / 2, width - inch, height - inch,
                      leftPadding=0, bottomPadding=0, rightPadding=0, topPadding=0)
            f.addFromList([p1, p2], canvas)

            document.pageTemplate.frames[0].height -= h1 + h2 + inch / 2
            document.pageTemplate.frames[1].height -= h1 + h2 + inch / 2

            canvas.saveState()
            canvas.setStrokeColorRGB(0, 0, 0)
            canvas.line(width / 2, inch / 2, width / 2, height - inch - h1 - h2)
            canvas.restoreState()

        def prepare_later_page(canvas, document):
            canvas.saveState()
            canvas.setStrokeColorRGB(0, 0, 0)
            canvas.line(width / 2, inch / 2, width / 2, height - inch / 2)
            canvas.restoreState()

        def getStyleSheet():
            stylesheet = StyleSheet1()
            stylesheet.add(ParagraphStyle(name='Normal',
                                          fontName='Times-Roman',
                                          fontSize=8,
                                          leading=10,
                                          spaceAfter=18))
            stylesheet.add(ParagraphStyle(name='SlideNumber',
                                          parent=stylesheet['Normal'],
                                          alignment=TA_RIGHT,
                                          fontSize=6,
                                          leading=8,
                                          rightIndent=3,
                                          spaceAfter=0))
            stylesheet.add(ParagraphStyle(name='Heading',
                                          parent=stylesheet['Normal'],
                                          fontSize=20,
                                          leading=24,
                                          alignment=TA_CENTER,
                                          spaceAfter=0))
            stylesheet.add(ParagraphStyle(name='SubHeading',
                                          parent=stylesheet['Normal'],
                                          fontSize=16,
                                          leading=20,
                                          alignment=TA_CENTER))
            return stylesheet

        styles = getStyleSheet()

        items = presentation.items.filter(hidden=False)

        content = []

        for index, item in enumerate(items):
            text = []
            values = item.get_fieldvalues(owner=request.user)
            for value in values:
                log.debug('value for cleaning = %s' % value.value)
                value.value = remove_rels_from_a_tags(value.value)
                log.debug('cleaned value = %s' % value.value)
                text.append('<b>%s</b>: %s<br />' % (value.resolved_label, value.value))
            annotation = item.annotation
            if annotation:
                text.append('<b>%s</b>: %s<br />' % ('Annotation', annotation))
            try:
                p = Paragraph(''.join(text), styles['Normal'])
            except (AttributeError, KeyError, IndexError):
                # this sometimes triggers an error in reportlab
                p = None
            if p:
                image = get_image_for_record(item.record, presentation.owner, 100, 100, passwords)
                if image:
                    try:
                        i = flowables.Image(image, kind='proportional',
                                            width=1 * inch, height=1 * inch)
                        p = flowables.ParagraphAndImage(p, i)
                    except IOError:
                        pass
                content.append(flowables.KeepTogether(
                    [Paragraph('%s/%s' % (index + 1, len(items)), styles['SlideNumber']), p]))

        first_template = PageTemplate(id='First',
                                      frames=[column_frame(inch / 2), column_frame(width / 2 + 0.25 * inch)],
                                      pagesize=pagesize,
                                      onPage=prepare_first_page)
        later_template = PageTemplate(id='Later',
                                      frames=[column_frame(inch / 2), column_frame(width / 2 + 0.25 * inch)],
                                      pagesize=pagesize,
                                      onPage=prepare_later_page)

        doc = DocTemplate(response)
        doc.addPageTemplates([first_template, later_template])
        doc.build(content)

        response['Content-Disposition'] = 'filename="' + smart_str(presentation.title) + '.pdf"'

        return response