Example #1
0
def conv(xml_in, html_out='out.html', template_name='html.pt', xpath_filter='//entry'):

    if not xml_in:
        raise ValueError('No XML input file specified (-i|--xml-in)')

    entries = util.get_entries(xml_in, xpath_filter)
    template = env.get_template(template_name)
    html = template.render(entries=entries,
            view=util.JinjaView())
    with open(html_out, 'wb') as fp:
        fp.write(html.encode('utf8'))
    return html_out
def conv(schedule_xml, # schedule XML string or schedule XML filename
        date_str,      # YYYY-MM-DD
        rooms,         # list of rooms
        hour_start=0,  # schedule starts
        hour_end=24,   # schedule ends
        resolution=15, # timeslot resolution in minutes
        caption=None,  # caption of table
        weekday=None,  # weekday name
        event_renderer=None):

    entries = util.get_entries(schedule_xml, '//day[@date="{}"]/entry'.format(date_str))

    row_headers = list()
    for hour in range(hour_start, hour_end + 1):
        for minute in range(0, 60, resolution):
            row_headers.append('{:02}:{:02}h'.format(hour, minute))
    tb = table.Table(60/resolution * (hour_end - hour_start) , len(rooms))
    tb.caption = caption
    tb.col_headers = rooms
    tb.row_headers = row_headers
    tb.weekday = weekday

    for e in entries:
        # determine starting row of event
        e_start = e.start.text      # format '0700'
        s_hour = int(e_start[:2])
        s_minute = int(e_start[2:])
        s_row = (s_hour - hour_start) * (60 / resolution) + s_minute / resolution

        # calculate row span over multiple time slots
        s_duration = int(e.duration)
        rowspan = s_duration / resolution 

        # determine col of event
        if e.room == 'ALL':
            # span over all columns
            s_col = 0
            colspan = len(rooms)
            tb.addCell(s_row, s_col, rowspan=rowspan, colspan=colspan, event=e)
        else:
            for room in e.room.text.split(','):
                if room in rooms:
                    s_col = rooms.index(room)
                    colspan = 1
                    tb.addCell(s_row, s_col, rowspan=rowspan, colspan=colspan, event=e)

    return tb.render(event_renderer=event_renderer)
Example #3
0
def conv(xml_in=None, 
        html_out='brochure.html', 
        first_page_number=1, 
        pdf_converter=None, 
        pdf_filename=None, 
        imagedir=None,
        emptypage=False,
        fontpath='fonts',
        template='brochure_talks.pt'):

    if not xml_in:
        raise ValueError('No XML input file specified (-i|--xml-in)')

    if imagedir:
        for name in os.listdir(imagedir):
            filename  = os.path.join(imagedir, name)
            img = PIL.Image.open(filename)
            target_size = min(img.size)
            if img.size != (target_size, target_size):
                print 'Cropping {}'.format(filename)
                img2 = img.crop((0, 0, target_size, target_size))
                img2.save(filename)


    entries = list()
    for day in range(21, 26):
        date_str = '2014-07-{}'.format(day)
        entries_d = util.get_entries(xml_in, '//day[@date="{}"]/entry'.format(date_str))
        entries_d = [e for e in entries_d if e.category]
        entries.append(dict(entries=entries_d,
                            date_text=datetime.strptime(date_str, '%Y-%m-%d').strftime('%A'),
                            date_str=date_str))

    speakers = list()
    speakers_seen = set()
    for e in util.get_entries(xml_in, '//day/entry'):
        for speaker in e.speakers or []:
            speaker_name = speaker.speaker.name
            speaker_description = speaker.speaker.description
            speaker_image_url = speaker.speaker.image
            speaker_has_content = 'has-content' if len(speaker_description.text or '')> 0 else 'has-no-content'
            speaker_image_file = ''
            speaker_image_found = False
            if imagedir:
                speaker_image_file = os.path.join(os.path.abspath(imagedir), speaker.speaker.attrib['id'])
                for ext in ('.png', '.jpg', '.gif'):
                    if os.path.exists(speaker_image_file + ext):
                        speaker_image_file += ext
                        speaker_image_found = True
                        break

            if not speaker_image_found:
                print 'No speaker image found for {} ({})'.format(speaker_name.text.encode('utf8'), speaker.speaker.attrib['id'])


            if not speaker_name in speakers_seen:
                speakers.append(dict(name=speaker_name,
                                    name_lower=unicode(speaker_name).lower(),
                                    description=speaker_description,
                                    image_file=speaker_image_file,
                                    has_content=speaker_has_content,
                                    has_image=speaker_image_found,
                                    image_url=speaker_image_url))
                speakers_seen.add(speaker_name)

    speakers = sorted(speakers, key=operator.itemgetter('name_lower'))
    print '{} speakers found'.format(len(speakers))

    template = env.get_template(template)
    html = template.render(
            first_page_number=int(first_page_number) - 1,
            second_page_number=int(first_page_number) +3,
            day_entries=entries,
            speakers=speakers,
            emptypage=emptypage,
            view=util.JinjaView())

    with open(html_out, 'wb') as fp:
        print 'HTML output written to "{}"'.format(html_out)
        fp.write(html.encode('utf8'))

    if pdf_converter in ('princexml', 'pdfreactor', 'pdfreactor7', 'remote-princexml', 'remote-pdfreactor'):

        # write HTML file to a dedicated scratch directory
        tmpd = tempfile.mkdtemp()
        html_filename  = os.path.join(tmpd, 'index.html')
        with open(html_filename, 'wb') as fp:
            fp.write(html.encode('utf-8'))

        # copy over conversion resources
        resources_dir = os.path.join(os.path.dirname(__file__), 'templates', 'resources')
        for dirname, dirnames, filenames in os.walk(resources_dir):
            for fname in filenames:
                shutil.copy(os.path.join(dirname, fname), tmpd)

        if fontpath and os.path.exists(fontpath):
            for filename in os.listdir(fontpath):
                shutil.copy(os.path.join(fontpath, filename), tmpd)

        if pdf_converter in ('princexml', 'pdfreactor', 'pdfreactor7'):
            # local pdf generation through PrinceXML or PDFreactor

            if pdf_filename:
                out_pdf = pdf_filename
            else:
                out_pdf = '{}.pdf'.format(os.path.splitext(html_filename)[0])
            if pdf_converter == 'princexml':
                cmd = 'prince -v "{}" -o "{}"'.format(html_filename, out_pdf)
            elif pdf_converter == 'pdfreactor':
                cmd = 'pdfreactor --disablefontembedding "{}" "{}"'.format(html_filename, out_pdf)
            elif pdf_converter == 'pdfreactor7':
                cmd = '/opt/PDFreactor7/bin/pdfreactor --disablefontembedding "{}" "{}"'.format(html_filename, out_pdf)
            print 'Running: {}'.format(cmd)
            proc = subprocess.Popen(cmd, shell=True)
            status = proc.wait()
            print 'Exit code: {}'.format(status)
            if status != 0:
                raise RuntimeError('PDF generation failed')
            print 'PDF written to "{}"'.format(out_pdf)
            return out_pdf

        elif pdf_converter in ('remote-princexml', 'remote-pdfreactor'):
            # remote pdf generation through PrinceXML or PDFreactor
            # through https://pp-server.zopyx.com

            server_url = os.environ['PP_SERVER_URL']
            authorization_token = os.environ['PP_AUTHORIZATION_TOKEN']
            output_filename = tempfile.mktemp(suffix='.pdf', dir=tmpd)
            result = pdf(source_directory=tmpd,
                         converter=pdf_converter.replace('remote-', ''),
                         output=output_filename,
                         server_url=server_url,
                         authorization_token=authorization_token,
                         verbose=True)

            if result['status'] != 'OK':
                raise RuntimeError('Remote PDF generation failed')

            print 'PDF written to "{}"'.format(result['output_filename'])
            return result['output_filename']