# Using the ReportLab toolkit from within Zope to produce a catalog.
#
# Adapted from original code, rlzope.py by Jerome Alet <alet@unice.fr>
# available here: http://cortex.unice.fr/~jerome/RLfromZope/
#
# Dinu Gherman, dinu (at) mac dot com


import string, cStringIO, urllib, re
try :
    from Shared.reportlab.platypus.flowables import Image
    from Shared.reportlab.platypus.paragraph import Paragraph
    from Shared.reportlab.platypus.doctemplate import *
    from Shared.reportlab.lib.units import inch
    from Shared.reportlab.lib import styles
    from Shared.PIL import Image as PIL_Image
except ImportError :
    from reportlab.platypus.flowables import Image
    from reportlab.platypus.paragraph import Paragraph
    from reportlab.platypus.doctemplate import *
    from reportlab.lib.units import inch
    from reportlab.lib import styles
    from PIL import Image as PIL_Image


def getImages(maxIndex=-1):
    "Fetch some exciting pictures."
    
    site = 'http://www.lubies.com'
    html = urllib.urlopen(site+'/hlw/aubade.asp').read()
    pattern = 'popup.asp\?id_photo\=(\d+)'
    pat = re.compile(pattern)
    numbers = re.findall(pat, html)

    jpgs = []
    for num in numbers[:maxIndex]:
       url = site + "/hlw/admin/dspimg2.asp?id_photo=" + num
       jpg = urllib.urlopen(url).read()
       jpgs.append(jpg)

    return jpgs


class MyPDFDoc :
    class MyPageTemplate(PageTemplate) :
        """Our own page template."""
        def __init__(self, parent) :
            """Initialise our page template."""
            #
            # we must save a pointer to our parent somewhere
            self.parent = parent

            # Our doc is made of a single frame
            content = Frame(0.75 * inch, 0.5 * inch, parent.document.pagesize[0] - 1.25 * inch, parent.document.pagesize[1] - (1.5 * inch))
            PageTemplate.__init__(self, "MyTemplate", [content])

        def beforeDrawPage(self, canvas, doc) :
            """Draws a logo and an contribution message on each page."""
            someText = "A sample catalog generated with an external Zope method and ReportLab"
            canvas.saveState()
            canvas.setFont('Times-Roman', 10)
            canvas.drawCentredString(inch + (doc.pagesize[0] - (1.5 * inch)) / 2, 0.25 * inch, someText)
            canvas.restoreState()

    def __init__(self, context, filename) :
        # save some datas
        self.context = context
        self.built = 0
        self.objects = []

        # we will build an in-memory document
        # instead of creating an on-disk file.
        self.report = cStringIO.StringIO()

        # initialise a PDF document using ReportLab's platypus
        self.document = BaseDocTemplate(self.report)

        # add our page template
        # (we could add more than one, but I prefer to keep it simple)
        self.document.addPageTemplates(self.MyPageTemplate(self))

        # get the default style sheets
        self.StyleSheet = styles.getSampleStyleSheet()

        # then build a simple doc with ReportLab's platypus
        url = self.escapexml(context.absolute_url())
        urlfilename = self.escapexml(context.absolute_url() + '/%s' % filename)

        for jpg in getImages(10):
            self.append(Image(cStringIO.StringIO(jpg)))
            self.append(Spacer(0, 10))

        # generation réelle du document PDF
        self.document.build(self.objects)
        self.built = 1

    def __str__(self) :
        """Returns the PDF document as a string of text, or None if it's not ready yet."""
        if self.built :
            return self.report.getvalue()
        else :
            return None

    def append(self, object) :
        """Appends an object to our platypus "story" (using ReportLab's terminology)."""
        self.objects.append(object)

    def escapexml(self, s) :
        """Escape some xml entities."""
        s = string.strip(s)
        s = string.replace(s, "&", "&amp;")
        s = string.replace(s, "<", "&lt;")
        return string.replace(s, ">", "&gt;")


def rlzopecatalog(self) :
    """A sample external method to show people how to use ReportLab from within Zope."""
    try:
        #
        # which file/object name to use ?
        # append ?name=xxxxx to rlzope's url to
        # choose another name
        filename = self.REQUEST.get("name", "catalog.pdf")
        if filename[-4:] != '.pdf' :
            filename = filename + '.pdf'

        # tell the browser we send some PDF document
        # with the requested filename

        # get the document's content itself as a string of text
        content = str(MyPDFDoc(self, filename))

        # we will return it to the browser, but before that we also want to
        # save it into the ZODB into the current folder
        try :
            self.manage_addFile(id = filename, file = content, title = "A sample PDF document produced with ReportLab", precondition = '', content_type = "application/pdf")
        except :
            # it seems an object with this name already exists in the ZODB:
            # it's more secure to not replace it, since we could possibly
            # destroy an important PDF document of this name.
            pass
        self.REQUEST.RESPONSE.setHeader('Content-Type', 'application/pdf')
        self.REQUEST.RESPONSE.setHeader('Content-Disposition', 'attachment; filename=%s' % filename)
    except:
        import traceback, sys, cgi
        content = sys.stdout = sys.stderr = cStringIO.StringIO()
        self.REQUEST.RESPONSE.setHeader('Content-Type', 'text/html')
        traceback.print_exc()
        sys.stdout = sys.__stdout__
        sys.stderr = sys.__stderr__
        content = '<html><head></head><body><pre>%s</pre></body></html>' % cgi.escape(content.getvalue())

    # then we also return the PDF content to the browser
    return content

