Пример #1
0
    def references(self):
        """Reference export for single record in datatables format.

        :returns: list
            List of lists where every item represents a datatables row.
            A row consists of [reference, num_citations]
        """
        from invenio_search.api import Query

        out = []
        references = self.record.get('references')
        if references:
            refs_to_get_from_es = [
                ref['recid'] for ref in references if ref.get('recid')
            ]
            es_query = ' or '.join(
                ['control_number:' + str(recid) for recid in refs_to_get_from_es]
            )
            es_query = Query(es_query).search()
            es_query.body.update({
                'size': 9999
            })
            refs_from_es = {
                record['control_number']: record for record in es_query.records()
            }

            for reference in references:
                row = []
                if 'recid' in reference:
                    recid = reference['recid']
                    ref_record = refs_from_es.get(str(recid))
                    if ref_record:
                        row.append(render_template_to_string(
                            "references.html",
                            record=ref_record,
                            reference=reference
                        ))
                        row.append(ref_record.get('citation_count', ''))
                        out.append(row)
                        continue

                row.append(render_template_to_string(
                    "references.html",
                    reference=reference))
                row.append('')
                out.append(row)

        return out
Пример #2
0
def format_records(records, of='hb', ln=None, **ctx):
    """Return records using Jinja template."""
    from flask import request
    from invenio_base.i18n import wash_language
    from .registry import export_formats

    of = of.lower()
    jrec = request.values.get('jrec', ctx.get('jrec', 1), type=int)
    rg = request.values.get('rg', ctx.get('rg', 10), type=int)
    ln = ln or wash_language(request.values.get('ln', cfg['CFG_SITE_LANG']))
    ot = (request.values.get('ot', ctx.get('ot')) or '').split(',')

    if jrec > records:
        jrec = rg * (records // rg) + 1

    context = dict(
        of=of, jrec=jrec, rg=rg, ln=ln, ot=ot,
        facets={},
        time=time,
        records=records,
        export_formats=export_formats,
        format_record=format_record,
        **TEMPLATE_CONTEXT_FUNCTIONS_CACHE.template_context_functions
    )
    context.update(ctx)
    return render_template_to_string(
        ['format/records/%s.tpl' % of,
         'format/records/%s.tpl' % of[0],
         'format/records/%s.tpl' % get_output_format_content_type(of).
            replace('/', '_')],
        **context)
Пример #3
0
    def citations(self):
        """Citation export for single record in datatables format.

        :returns: list
            List of lists where every item represents a datatables row.
            A row consists of [reference, num_citations]
        """
        from invenio_search.api import Query

        out = []
        row = []
        recid = self.record['control_number']
        es_query = Query('refersto:' + str(recid)).search()
        es_query.body.update({
            'sort': [{'citation_count': {'order': 'desc'}}],
            'size': 9999
        })
        citations = es_query.records()

        for citation in citations:
            row.append(render_template_to_string("citations.html",
                                                 record=citation))
            row.append(citation.get('citation_count', ''))
            out.append(row)
            row = []

        return out
def format_record(record,
                  of,
                  ln=None,
                  verbose=0,
                  search_pattern=None,
                  xml_record=None,
                  user_info=None,
                  **kwargs):
    """Format a record in given output format.

    Return a formatted version of the record in the specified
    language, search pattern, and with the specified output format.
    The function will define which format template must be applied.

    The record to be formatted can be specified with its ID (with
    'recID' parameter) or given as XML representation (with
    'xml_record' parameter). If 'xml_record' is specified 'recID' is
    ignored (but should still be given for reference. A dummy recid 0
    or -1 could be used).
    """
    ln = ln or cfg['CFG_SITE_LANG']

    template = decide_format_template(record, of)

    out = render_template_to_string(
        ['format/record/{0}'.format(template), template],
        recid=record['recid'],
        record=record,
        format_record=format_record,
        **(kwargs or {}))

    return out
Пример #5
0
    def test_email_text_template(self):
        """
        Test email text template engine.
        """
        from invenio_ext.template import render_template_to_string

        contexts = {
            'ctx1': {'content': 'Content 1'},
            'ctx2': {'content': 'Content 2', 'header': 'Header 2'},
            'ctx3': {'content': 'Content 3', 'footer': 'Footer 3'},
            'ctx4': {'content': 'Content 4', 'header': 'Header 4', 'footer': 'Footer 4'}
        }

        msg_content = """Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: %s
From: [email protected]
To: [email protected]"""

        for name, ctx in iteritems(contexts):
            msg = render_template_to_string('mail_text.tpl', **ctx)
            send_email('*****@*****.**', ['*****@*****.**'], subject=name,
                       **ctx)
            email = sys.stdout.getvalue()
            self.assertIn(msg_content % name, email)
            self.assertIn(msg, email)
            self.flush_mailbox()
Пример #6
0
    def test_simple_email_header(self):
        """
        Test simple email header.
        """
        from invenio_base.globals import cfg
        from invenio_ext.template import render_template_to_string

        msg_content = """Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Subject
From: [email protected]
To: %s""" % (cfg['CFG_SITE_ADMIN_EMAIL'], )

        msg = render_template_to_string('mail_text.tpl', content='Content')

        self.flush_mailbox()
        send_email('*****@*****.**', ['*****@*****.**'], subject='Subject',
                   content='Content')
        email = self.stream.getvalue()
        self.assertIn(msg_content, email)
        self.assertIn(self.ADMIN_MESSAGE, email)
        self.assertNotIn('Bcc:', email)
        self.assertIn(msg, email)
        self.flush_mailbox()

        send_email('*****@*****.**', '*****@*****.**', subject='Subject',
                   content='Content')
        email = self.stream.getvalue()
        self.assertIn(msg_content, email)
        self.assertIn(self.ADMIN_MESSAGE, email)
        self.assertNotIn('Bcc:', email)
        self.assertIn(msg, email)
        self.flush_mailbox()
Пример #7
0
    def test_email_html_template(self):
        """
        Test email html template engine.
        """
        from invenio_ext.template import render_template_to_string

        contexts = {
            'ctx1': {'html_content': '<b>Content 1</b>'},
            'ctx2': {'html_content': '<b>Content 2</b>',
                     'html_header': '<h1>Header 2</h1>'},
            'ctx3': {'html_content': '<b>Content 3</b>',
                     'html_footer': '<i>Footer 3</i>'},
            'ctx4': {'html_content': '<b>Content 4</b>',
                     'html_header': '<h1>Header 4</h1>',
                     'html_footer': '<i>Footer 4</i>'}
        }

        def strip_html_key(ctx):
            return dict(map(lambda (k, v): (k[5:], v), iteritems(ctx)))

        for name, ctx in iteritems(contexts):
            msg = render_template_to_string('mail_html.tpl',
                                            **strip_html_key(ctx))
            send_email('*****@*****.**', ['*****@*****.**'], subject=name,
                       content='Content Text', **ctx)
            email = sys.stdout.getvalue()
            self.assertIn('Content-Type: multipart/alternative;', email)
            self.assertIn('Content Text', email)
            self.assertIn(msg, email)
            self.flush_mailbox()
def template_context_function(recID):
    """
    Displays next-hit/previous-hit/back-to-search links
    on the detailed record pages in order to be able to quickly
    flip between detailed record pages
    :param recID: detailed record ID
    :type recID: string
    :return: html output
    """
    if recID is None:
        return ""
    # this variable is set to zero so nothing is displayed
    if not cfg['CFG_WEBSEARCH_PREV_NEXT_HIT_LIMIT']:
        return ""

    # search for a specific record having not done
    # any search before
    try:
        last_query = session['websearch-last-query']
        recids = session["websearch-last-query-hits"]
    except:
        return ""

    if recids:
        return render_template_to_string(
            'records/back_to_search_links.html',
            recID=int(recID),
            last_query=cfg['CFG_SITE_URL'] +
            last_query,
            recids=recids)
    else:
        # did not rich the limit CFG_WEBSEARCH_PREV_NEXT_HIT_LIMIT,
        # so nothing is displayed
        return ""
Пример #9
0
def template_context_function(recID):
    """
    Displays next-hit/previous-hit/back-to-search links
    on the detailed record pages in order to be able to quickly
    flip between detailed record pages
    :param recID: detailed record ID
    :type recID: string
    :return: html output
    """
    if recID is None:
        return ""
    # this variable is set to zero so nothing is displayed
    if not cfg['CFG_WEBSEARCH_PREV_NEXT_HIT_LIMIT']:
        return ""

    # search for a specific record having not done
    # any search before
    try:
        last_query = session['websearch-last-query']
        recids = session["websearch-last-query-hits"]
    except:
        return ""

    if recids:
        return render_template_to_string('records/back_to_search_links.html',
                                         recID=int(recID),
                                         last_query=cfg['CFG_SITE_URL'] +
                                         last_query,
                                         recids=recids)
    else:
        # did not rich the limit CFG_WEBSEARCH_PREV_NEXT_HIT_LIMIT,
        # so nothing is displayed
        return ""
Пример #10
0
def email_alert(mapper, connection, target):
    """ Sends email alerts to message recipients. """
    from invenio_ext.template import render_template_to_string
    from invenio_ext.email import send_email, scheduled_send_email
    m = target
    is_reminder =  m.received_date is not None \
        and m.received_date > datetime.now()

    alert = send_email
    if is_reminder:
        alert = lambda *args, **kwargs: scheduled_send_email(*args,
                                                             other_bibtasklet_arguments=[
                                                                 m.received_date.strftime(datetext_format)],
                                                             **kwargs)

    for u in m.recipients:
        if isinstance(u.settings, dict) and \
                u.settings.get('webmessage_email_alert', True):
            try:
                alert(
                    cfg['CFG_WEBCOMMENT_ALERT_ENGINE_EMAIL'],
                    u.email,
                    subject=m.subject,
                    content=render_template_to_string(
                        'messages/email_alert.html',
                        message=m, user=u))
            except:
                # FIXME tests are not in request context
                pass
Пример #11
0
def format_record(record, of, ln=None, verbose=0, search_pattern=None,
                  xml_record=None, user_info=None, **kwargs):
    """Format a record in given output format.

    Return a formatted version of the record in the specified
    language, search pattern, and with the specified output format.
    The function will define which format template must be applied.

    The record to be formatted can be specified with its ID (with
    'recID' parameter) or given as XML representation (with
    'xml_record' parameter). If 'xml_record' is specified 'recID' is
    ignored (but should still be given for reference. A dummy recid 0
    or -1 could be used).
    """
    ln = ln or cfg['CFG_SITE_LANG']

    template = decide_format_template(record, of)

    out = render_template_to_string(
        ['format/record/{0}'.format(template), template],
        recid=record['recid'],
        record=record,
        format_record=format_record,
        **(kwargs or {})
    )

    return out
def format_records(records, of='hb', ln=None, **ctx):
    """Return records using Jinja template."""
    from flask import request
    from invenio_base.i18n import wash_language
    from .registry import export_formats

    of = of.lower()
    jrec = request.values.get('jrec', ctx.get('jrec', 1), type=int)
    rg = request.values.get('rg', ctx.get('rg', 10), type=int)
    ln = ln or wash_language(request.values.get('ln', cfg['CFG_SITE_LANG']))
    ot = (request.values.get('ot', ctx.get('ot')) or '').split(',')

    if jrec > records:
        jrec = rg * (records // rg) + 1

    context = dict(
        of=of,
        jrec=jrec,
        rg=rg,
        ln=ln,
        ot=ot,
        facets={},
        time=time,
        records=records,
        export_formats=export_formats,
        format_record=format_record,
        **TEMPLATE_CONTEXT_FUNCTIONS_CACHE.template_context_functions)
    context.update(ctx)
    return render_template_to_string([
        'format/records/%s.tpl' % of,
        'format/records/%s.tpl' % of[0],
        'format/records/%s.tpl' %
        get_output_format_content_type(of).replace('/', '_')
    ], **context)
Пример #13
0
    def __call__(self, field, **kwargs):
        template = 'deposit/jsonwidget.html'
        field_id = kwargs.pop('id', field.id)

        return HTMLString(
            render_template_to_string(template,
                                      field=field,
                                      field_id=field_id,
                                      **kwargs))
Пример #14
0
    def __call__(self, field, **kwargs):
        """Render PLUpload widget."""
        field_id = kwargs.pop('id', field.id)
        kwargs['class'] = u'plupload'

        return HTMLString(
            render_template_to_string(self.template,
                                      field=field,
                                      field_id=field_id,
                                      **kwargs))
Пример #15
0
    def render_portalbox_bodies(self, templates):
        """Get a list of rendered portal boxes for this user collection."""
        ctx = {
            'community': self,
        }

        return map(
            lambda t: render_template_to_string(t, **ctx),
            templates
        )
Пример #16
0
 def __str__(self):
     uid = current_user.get_id()
     dbquery.update_user_inbox_for_reminders(uid)
     unread = db.session.query(db.func.count(UserMsgMESSAGE.id_msgMESSAGE)).\
         filter(db.and_(
             UserMsgMESSAGE.id_user_to == uid,
             UserMsgMESSAGE.status == cfg[
                 'CFG_WEBMESSAGE_STATUS_CODE']['NEW']
         )).scalar()
     return render_template_to_string(
         "messages/menu_item.html", unread=unread)
    def widget(self):
        user = User.query.get(current_user.get_id())
        tag_count = user.tags_query.count()

        record_count = Record.query.join(WtgTAGRecord)\
            .join(WtgTAG)\
            .filter(WtgTAG.user == user).count()

        return render_template_to_string('tags/user_settings.html',
                                         tag_count=tag_count,
                                         record_count=record_count)
Пример #18
0
    def widget(self):
        user = User.query.get(current_user.get_id())
        tag_count = user.tags_query.count()

        record_count = Record.query.join(WtgTAGRecord)\
            .join(WtgTAG)\
            .filter(WtgTAG.user == user).count()

        return render_template_to_string(
            'tags/user_settings.html',
            tag_count=tag_count,
            record_count=record_count)
    def __call__(self, field, **kwargs):
        template = 'deposit/jsonwidget.html'
        field_id = kwargs.pop('id', field.id)

        return HTMLString(
            render_template_to_string(
                template,
                field=field,
                field_id=field_id,
                **kwargs
            )
        )
Пример #20
0
    def __call__(self, field, **kwargs):
        """Render given field using a tempalte.

        :param field: field that should be rendered.
        :param template: path to Jinja template.
        :type template: str
        """
        template = kwargs.pop('template', field.template)
        field_id = kwargs.pop('id', field.id)

        return HTMLString(
            render_template_to_string(template,
                                      field=field,
                                      field_id=field_id,
                                      **kwargs))
Пример #21
0
    def widget(self):
        uid = current_user.get_id()
        unread = db.session.query(db.func.count(UserMsgMESSAGE.id_msgMESSAGE)).\
            filter(db.and_(
                UserMsgMESSAGE.id_user_to == uid,
                UserMsgMESSAGE.status == current_app.config[
                    'CFG_WEBMESSAGE_STATUS_CODE']['NEW']
            )).scalar()

        total = db.session.query(db.func.count(UserMsgMESSAGE.id_msgMESSAGE)).\
            filter(
                UserMsgMESSAGE.id_user_to == uid
        ).scalar()

        template = """
{{  _("You have %(x_num_new)d new messages out of %(x_num_total)d messages.",
      x_num_new=unread, x_num_total=total) }}
"""
        return render_template_to_string(template, _from_string=True,
                                         unread=unread, total=total)
Пример #22
0
    def test_email_text_template(self):
        """
        Test email text template engine.
        """
        from invenio_ext.template import render_template_to_string

        contexts = {
            'ctx1': {
                'content': 'Content 1'
            },
            'ctx2': {
                'content': 'Content 2',
                'header': 'Header 2'
            },
            'ctx3': {
                'content': 'Content 3',
                'footer': 'Footer 3'
            },
            'ctx4': {
                'content': 'Content 4',
                'header': 'Header 4',
                'footer': 'Footer 4'
            }
        }

        msg_content = """Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: %s
From: [email protected]
To: [email protected]"""

        for name, ctx in iteritems(contexts):
            msg = render_template_to_string('mail_text.tpl', **ctx)
            send_email('*****@*****.**', ['*****@*****.**'],
                       subject=name,
                       **ctx)
            email = sys.stdout.getvalue()
            self.assertIn(msg_content % name, email)
            self.assertIn(msg, email)
            self.flush_mailbox()
Пример #23
0
    def test_email_html_template(self):
        """
        Test email html template engine.
        """
        from invenio_ext.template import render_template_to_string

        contexts = {
            'ctx1': {
                'html_content': '<b>Content 1</b>'
            },
            'ctx2': {
                'html_content': '<b>Content 2</b>',
                'html_header': '<h1>Header 2</h1>'
            },
            'ctx3': {
                'html_content': '<b>Content 3</b>',
                'html_footer': '<i>Footer 3</i>'
            },
            'ctx4': {
                'html_content': '<b>Content 4</b>',
                'html_header': '<h1>Header 4</h1>',
                'html_footer': '<i>Footer 4</i>'
            }
        }

        def strip_html_key(ctx):
            return dict(map(lambda (k, v): (k[5:], v), iteritems(ctx)))

        for name, ctx in iteritems(contexts):
            msg = render_template_to_string('mail_html.tpl',
                                            **strip_html_key(ctx))
            send_email('*****@*****.**', ['*****@*****.**'],
                       subject=name,
                       content='Content Text',
                       **ctx)
            email = sys.stdout.getvalue()
            self.assertIn('Content-Type: multipart/alternative;', email)
            self.assertIn('Content Text', email)
            self.assertIn(msg, email)
            self.flush_mailbox()
Пример #24
0
    def open_tag(self, subfield, **kwargs):
        """Render open tag."""
        if self.html_tag:
            if subfield.name.endswith('__input__'):
                return '<%s>' % self.html_tag
            else:
                ctx = {}
                if (isinstance(subfield.data, six.string_types)):
                    ctx['value'] = subfield.data
                elif subfield.data:
                    ctx.update(subfield.data)

                return (
                    '<%s %s><button type="button" class="close remove-element"'
                    ' data-dismiss="alert">&times;</button>'
                    '<span class="tag-title">%s</span>' %
                    (self.html_tag,
                     html_params(class_=self.class_ + ' ' +
                                 kwargs.get('class_', '')),
                     render_template_to_string(
                         self.template, _from_string=True, **ctx)))
        return ''
Пример #25
0
def render_citations(recid):
    """Citation export for single record in datatables format.

        :returns: list
            List of lists where every item represents a datatables row.
            A row consists of [reference, num_citations]
    """
    out = []
    row = []
    es_query = Query('refersto:' + str(recid)).search()
    es_query.body.update({
        'sort': [{'citation_count': {'order': 'desc'}}]
    })
    citations = es_query.records()

    for citation in citations:
        row.append(render_template_to_string("citations.html",
                                             record=citation, reference=None))
        row.append(citation.get('citation_count', ''))
        out.append(row)
        row = []

    return out
Пример #26
0
    def test_simple_email_header(self):
        """
        Test simple email header.
        """
        from invenio_base.globals import cfg
        from invenio_ext.template import render_template_to_string

        msg_content = """Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: Subject
From: [email protected]
To: %s""" % (cfg['CFG_SITE_ADMIN_EMAIL'], )

        msg = render_template_to_string('mail_text.tpl', content='Content')

        self.flush_mailbox()
        send_email('*****@*****.**', ['*****@*****.**'],
                   subject='Subject',
                   content='Content')
        email = self.stream.getvalue()
        self.assertIn(msg_content, email)
        self.assertIn(self.ADMIN_MESSAGE, email)
        self.assertNotIn('Bcc:', email)
        self.assertIn(msg, email)
        self.flush_mailbox()

        send_email('*****@*****.**',
                   '*****@*****.**',
                   subject='Subject',
                   content='Content')
        email = self.stream.getvalue()
        self.assertIn(msg_content, email)
        self.assertIn(self.ADMIN_MESSAGE, email)
        self.assertNotIn('Bcc:', email)
        self.assertIn(msg, email)
        self.flush_mailbox()
Пример #27
0
 def tplEqualToString(self, tpl, text, **ctx):
     self.assertEqual(
         render_template_to_string(tpl, _from_string=True, **ctx), text)
Пример #28
0
 def tplEqualToString(self, tpl, text, **ctx):
     self.assertEqual(render_template_to_string(tpl, _from_string=True, **ctx), text)
Пример #29
0
def forge_email(fromaddr, toaddr, subject, content, html_content='',
                html_images=None, usebcc=False, header=None, footer=None,
                html_header=None, html_footer=None, ln=None,
                charset=None, replytoaddr="", attachments=None, bccaddr=""):
    """Prepare email. Add header and footer if needed.
    @param fromaddr: [string] sender
    @param toaddr: [string or list-of-strings] list of receivers (if string, then
                   receivers are separated by ',')
    @param usebcc: [bool] True for using Bcc in place of To
    @param subject: [string] subject of the email
    @param content: [string] content of the email
    @param html_content: [string] html version of the email
    @param html_images: [dict] dictionary of image id, image path
    @param header: [string] None for the default header
    @param footer: [string] None for the default footer
    @param ln: language
    @charset: [string] the content charset. By default is None which means
    to try to encode the email as ascii, then latin1 then utf-8.
    @param replytoaddr: [string or list-of-strings] to be used for the
                        reply-to header of the email (if string, then
                        receivers are separated by ',')
    @param attachments: list of paths of files to be attached. Alternatively,
        every element of the list could be a tuple: (filename, mimetype)
    @param bccaddr: [string or list-of-strings] to be used for BCC header of the email
                    (if string, then receivers are separated by ',')
    @return: forged email as an EmailMessage object"""
    from invenio_ext.template import render_template_to_string

    ln = default_ln(ln)
    if html_images is None:
        html_images = {}

    content = render_template_to_string('mail_text.tpl',
                                        content=unicodifier(content),
                                        header=unicodifier(header),
                                        footer=unicodifier(footer)
                                        ).encode('utf8')

    if isinstance(toaddr, list):
        toaddr = ','.join(toaddr)

    if isinstance(bccaddr, list):
        bccaddr = ','.join(bccaddr)

    if isinstance(replytoaddr, list):
        replytoaddr = ','.join(replytoaddr)

    toaddr = remove_temporary_emails(toaddr)

    headers = {}
    kwargs = {'to': [], 'cc': [], 'bcc': []}

    if replytoaddr:
        headers['Reply-To'] = replytoaddr
    if usebcc:
        headers['Bcc'] = bccaddr
        kwargs['bcc'] = toaddr.split(',') + bccaddr.split(',')
        kwargs['to'] = ['Undisclosed.Recipients:']
    else:
        kwargs['to'] = toaddr.split(',')
    headers['From'] = fromaddr
    headers['Date'] = formatdate(localtime=True)
    headers['User-Agent'] = 'Invenio %s at %s' % (cfg['CFG_VERSION'],
                                                  cfg['CFG_SITE_URL'])

    if html_content:
        html_content = render_template_to_string(
            'mail_html.tpl',
            content=unicodifier(html_content),
            header=unicodifier(html_header),
            footer=unicodifier(html_footer)
        ).encode('utf8')

        msg_root = EmailMultiAlternatives(subject=subject, body=content,
                                          from_email=fromaddr,
                                          headers=headers, **kwargs)
        msg_root.attach_alternative(html_content, "text/html")

        # if not html_images:
        #    # No image? Attach the HTML to the root
        #    msg_root.attach(msg_text)
        # else:
        if html_images:
            # Image(s)? Attach the HTML and image(s) as children of a
            # "related" block
            msg_related = MIMEMultipart('related')
            # msg_related.attach(msg_text)
            for image_id, image_path in iteritems(html_images):
                attach_embed_image(msg_related, image_id, image_path)
            msg_root.attach(msg_related)
    else:
        msg_root = EmailMessage(subject=subject, body=content,
                                from_email=fromaddr, headers=headers, **kwargs)

    if attachments:
        _mimes = MimeTypes(strict=False)
        for attachment in attachments:
            try:
                mime = None
                if type(attachment) in (list, tuple):
                    attachment, mime = attachment
                if mime is None:
                    # Automatic guessing of mimetype
                    mime = _mimes.guess_type(attachment)[0]
                if mime is None:
                    ext = _mimes.guess_extension(getContentType(attachment))
                    mime = _mimes.guess_type("foo" + ext)[0]
                if not mime:
                    mime = 'application/octet-stream'
                part = MIMEBase(*mime.split('/', 1))
                part.set_payload(open(attachment, 'rb').read())
                Encoders.encode_base64(part)
                part.add_header(
                    'Content-Disposition',
                    'attachment; filename="%s"' %
                    os.path.basename(attachment))
                msg_root.attach(part)
            except:
                from invenio_ext.logging import register_exception
                register_exception(
                    alert_admin=True,
                    prefix="Can't attach %s" %
                    attachment)

    return msg_root
Пример #30
0
    def cache_record_oneline_views(self):
        from invenio_ext.template import render_template_to_string

        for record in self.records:
            render_template_to_string("citations.html", record=record, reference=None)
Пример #31
0
def create_config(force=False, no_ssl=False):
    """
    Create Apache configuration files for this site, keeping previous
    files in a backup copy.
    """
    import os
    import pwd
    import pkg_resources
    import sys
    import shutil
    from flask import current_app
    from jinja2 import TemplateNotFound
    from invenio_ext.template import render_template_to_string
    from invenio_utils.text import wrap_text_in_a_box

    CFG_ETCDIR = current_app.config.get('CFG_ETCDIR', '')

    def get_context():
        conf = current_app.config

        # Apache vhost conf file is distro specific, so analyze needs:
        # Gentoo (and generic defaults):
        listen_directive_needed = True
        ssl_pem_directive_needed = False
        ssl_pem_path = CFG_ETCDIR + '/apache/ssl/apache.pem'
        ssl_crt_path = CFG_ETCDIR + '/apache/ssl/server.crt'
        ssl_key_path = CFG_ETCDIR + '/apache/ssl/server.key'
        vhost_ip_address_needed = False
        wsgi_socket_directive_needed = False
        # Debian:
        if os.path.exists(os.path.sep + 'etc' + os.path.sep +
                          'debian_version'):
            listen_directive_needed = False
            ssl_pem_directive_needed = True
            ssl_pem_path = '/etc/apache2/ssl/apache.pem'
            ssl_crt_path = '/etc/apache2/ssl/server.crt'
            ssl_key_path = '/etc/apache2/ssl/server.key'
        # RHEL/SLC:
        if os.path.exists(os.path.sep + 'etc' + os.path.sep +
                          'redhat-release'):
            listen_directive_needed = False
            ssl_crt_path = '/etc/pki/tls/certs/localhost.crt'
            ssl_key_path = '/etc/pki/tls/private/localhost.key'
            vhost_ip_address_needed = True
            wsgi_socket_directive_needed = True
        # maybe we are using non-standard ports?
        vhost_site_url = conf.get('CFG_SITE_URL').replace("http://", "")
        if vhost_site_url.startswith("https://"):
            # The installation is configured to require HTTPS for any
            # connection
            vhost_site_url = vhost_site_url.replace("https://", "")
        vhost_site_url_port = '80'
        vhost_site_secure_url = conf.get('CFG_SITE_SECURE_URL').replace(
            "https://", "").replace("http://", "")
        vhost_site_secure_url_port = '443'
        if ':' in vhost_site_url:
            vhost_site_url, vhost_site_url_port = vhost_site_url.split(':', 1)
        if ':' in vhost_site_secure_url:
            vhost_site_secure_url, vhost_site_secure_url_port = \
                vhost_site_secure_url.split(':', 1)
        if vhost_site_url_port != '80' or vhost_site_secure_url_port != '443':
            listen_directive_needed = True

        static_root = current_app.config['COLLECT_STATIC_ROOT']
        if not os.path.exists(static_root):
            os.mkdir(static_root)

        def prepare_alias(filename):
            if os.path.isdir(os.path.join(static_root, filename)):
                return '/%s/' % (filename, )
            return '/%s' % (filename, )

        aliases = map(prepare_alias, os.listdir(static_root))

        apc1 = {'vhost_site_url_port': vhost_site_url_port,
                'servername': vhost_site_url,
                'serveralias': vhost_site_url.split('.')[0],
                'vhost_ip_address': vhost_ip_address_needed and
                _detect_ip_address() or '*',
                'wsgi_socket_directive_needed': wsgi_socket_directive_needed,
                'listen_directive_needed': listen_directive_needed,
                'aliases': aliases,
                }

        apc2 = {'vhost_site_url_port': vhost_site_secure_url_port,
                'servername': vhost_site_secure_url,
                'serveralias': vhost_site_secure_url.split('.')[0],
                'vhost_ip_address': vhost_ip_address_needed and
                _detect_ip_address() or '*',
                'wsgi_socket_directive_needed': wsgi_socket_directive_needed,
                'ssl_pem_directive': ssl_pem_directive_needed and
                'SSLCertificateFile %s' % ssl_pem_path or
                '#SSLCertificateFile %s' % ssl_pem_path,
                'ssl_crt_directive': ssl_pem_directive_needed and
                '#SSLCertificateFile %s' % ssl_crt_path or
                'SSLCertificateFile %s' % ssl_crt_path,
                'ssl_key_directive': ssl_pem_directive_needed and
                '#SSLCertificateKeyFile %s' % ssl_key_path or
                'SSLCertificateKeyFile %s' % ssl_key_path,
                'listen_directive_needed': listen_directive_needed,
                'aliases': aliases,
                }

        return [apc1, apc2]

    current_app.config.update(
        SYS_PREFIX=sys.prefix,
        CFG_RUNNING_AS_USER=pwd.getpwuid(os.getuid())[0],
        CFG_WSGIDIR=os.path.abspath(
            pkg_resources.resource_filename('invenio', '')))

    apache_conf_dir = current_app.instance_path + os.sep + 'apache'

    print(">>> Going to create Apache conf files...")
    conf_files = ['invenio-apache-vhost.conf', 'invenio-apache-vhost-ssl.conf']
    conf_files = conf_files[:1 if no_ssl else 2]

    if not os.path.exists(apache_conf_dir):
        os.mkdir(apache_conf_dir)

    for local_file, context in zip(conf_files,
                                   get_context()[:1 if no_ssl else 2]):
        print(">>> Writing %s ..." % local_file)

        try:
            apache_vhost_file = apache_conf_dir + os.sep + local_file
            if os.path.exists(apache_vhost_file):
                shutil.copy(apache_vhost_file,
                            apache_vhost_file + '.OLD')

            with open(apache_vhost_file, 'w') as f:
                out = render_template_to_string(local_file + '.tpl', os=os,
                                                **context)
                print(out, file=f)

        except TemplateNotFound:
            print("Could not find template %s".format(local_file),
                  file=sys.stderr)

    print(wrap_text_in_a_box("""\
Apache virtual host configuration file(s) for your Invenio site
was(were) created.  Please check created file(s) and activate virtual
host(s).  For example, you can put the following include statements in
your httpd.conf:\n

%s

Please see the INSTALL file for more details.
    """ % '\n\n'.join(tuple(map(
        lambda x: "Include " + apache_conf_dir.encode('utf-8') + os.sep + x,
        list(conf_files[:1 if no_ssl else 2]))))))
    print(">>> Apache conf files created.")
def template_context_function(id_bibrec, id_user):
    """Add tag editor.

    :param id_bibrec: ID of record
    :param id_user: user viewing the record (and owning the displayed tags)
    :return: HTML containing tag list
    """
    if id_user and id_bibrec:
        # Get user settings:
        user = User.query.get(id_user)
        user_settings = user.settings.get(
            'webtag', cfg['CFG_WEBTAG_DEFAULT_USER_SETTINGS'])

        if not user_settings['display_tags']:
            # Do not display if user turned off tags in settings
            return ''

        # Private
        query_results = db.session.query(WtgTAG, WtgTAGRecord.annotation)\
            .filter(WtgTAG.id == WtgTAGRecord.id_tag)\
            .filter(WtgTAGRecord.id_bibrec == id_bibrec)\
            .filter(WtgTAG.id_user == id_user)\
            .all()

        # Group tags
        if user_settings.get('display_tags_group', True):
            group_results = db.session.query(
                WtgTAG, WtgTAGRecord.annotation, Group.name
            ).join(Membership, Membership.id_user == id_user)\
                .filter(WtgTAG.id == WtgTAGRecord.id_tag)\
                .filter(WtgTAGRecord.id_bibrec == id_bibrec)\
                .filter(WtgTAG.group_access_rights >=
                        WtgTAG.ACCESS_LEVELS['View'])\
                .filter(WtgTAG.id_usergroup == Group.id)\
                .filter(WtgTAG.id_user != id_user)\
                .filter(Group.id == Membership.id_usergroup)\
                .all()

            for (tag, annotation, group_name) in group_results:
                tag.group_name = group_name
                query_results.append((tag, annotation))

        # Public tags
        # if user_settings.get('display_tags_public', True):

        tag_infos = []

        for (tag, annotation_text) in query_results:
            tag_info = dict(
                id=tag.id,
                name=tag.name,
                record_count=tag.record_count,
                annotation=annotation_text,
                label_classes='')

            tag_info['owned'] = (tag.id_user == id_user)
            tag_info['is_group'] = (tag.id_usergroup != 0)
            tag_info['is_private'] = not tag_info['is_group']

            if tag_info['is_private']:
                tag_info['label_classes'] += ' label-info'

            if tag_info['is_group']:
                tag_info['group_name'] = getattr(tag, 'group_name', '')

                tag_info['label_classes'] += ' label-success'
                if tag_info['owned']:
                    tag_info['label_classes'] += ' label-tag-owned'

            tag_info['popover_title'] = render_template_to_string(
                'tags/tag_popover_title.html',
                tag=tag_info,
                id_bibrec=id_bibrec)

            tag_info['popover_content'] = render_template_to_string(
                'tags/tag_popover_content.html',
                tag=tag_info,
                id_bibrec=id_bibrec)

            tag_infos.append(tag_info)
        return render_template_to_string(
            'tags/record_tags.html',
            tag_infos=tag_infos,
            id_bibrec=id_bibrec)
    else:
        return ''
Пример #33
0
def template_context_function(id_bibrec, id_user):
    """Add tag editor.

    :param id_bibrec: ID of record
    :param id_user: user viewing the record (and owning the displayed tags)
    :return: HTML containing tag list
    """
    if id_user and id_bibrec:
        # Get user settings:
        user = User.query.get(id_user)
        user_settings = user.settings.get(
            'webtag', cfg['CFG_WEBTAG_DEFAULT_USER_SETTINGS'])

        if not user_settings['display_tags']:
            # Do not display if user turned off tags in settings
            return ''

        # Private
        query_results = db.session.query(WtgTAG, WtgTAGRecord.annotation)\
            .filter(WtgTAG.id == WtgTAGRecord.id_tag)\
            .filter(WtgTAGRecord.id_bibrec == id_bibrec)\
            .filter(WtgTAG.id_user == id_user)\
            .all()

        # Group tags
        if user_settings.get('display_tags_group', True):
            group_results = db.session.query(
                WtgTAG, WtgTAGRecord.annotation, Group.name
            ).join(Membership, Membership.id_user == id_user)\
                .filter(WtgTAG.id == WtgTAGRecord.id_tag)\
                .filter(WtgTAGRecord.id_bibrec == id_bibrec)\
                .filter(WtgTAG.group_access_rights >=
                        WtgTAG.ACCESS_LEVELS['View'])\
                .filter(WtgTAG.id_usergroup == Group.id)\
                .filter(WtgTAG.id_user != id_user)\
                .filter(Group.id == Membership.id_usergroup)\
                .all()

            for (tag, annotation, group_name) in group_results:
                tag.group_name = group_name
                query_results.append((tag, annotation))

        # Public tags
        # if user_settings.get('display_tags_public', True):

        tag_infos = []

        for (tag, annotation_text) in query_results:
            tag_info = dict(id=tag.id,
                            name=tag.name,
                            record_count=tag.record_count,
                            annotation=annotation_text,
                            label_classes='')

            tag_info['owned'] = (tag.id_user == id_user)
            tag_info['is_group'] = (tag.id_usergroup != 0)
            tag_info['is_private'] = not tag_info['is_group']

            if tag_info['is_private']:
                tag_info['label_classes'] += ' label-info'

            if tag_info['is_group']:
                tag_info['group_name'] = getattr(tag, 'group_name', '')

                tag_info['label_classes'] += ' label-success'
                if tag_info['owned']:
                    tag_info['label_classes'] += ' label-tag-owned'

            tag_info['popover_title'] = render_template_to_string(
                'tags/tag_popover_title.html',
                tag=tag_info,
                id_bibrec=id_bibrec)

            tag_info['popover_content'] = render_template_to_string(
                'tags/tag_popover_content.html',
                tag=tag_info,
                id_bibrec=id_bibrec)

            tag_infos.append(tag_info)
        return render_template_to_string('tags/record_tags.html',
                                         tag_infos=tag_infos,
                                         id_bibrec=id_bibrec)
    else:
        return ''
Пример #34
0
def forge_email(fromaddr,
                toaddr,
                subject,
                content,
                html_content='',
                html_images=None,
                usebcc=False,
                header=None,
                footer=None,
                html_header=None,
                html_footer=None,
                ln=None,
                charset=None,
                replytoaddr="",
                attachments=None,
                bccaddr=""):
    """Prepare email. Add header and footer if needed.
    @param fromaddr: [string] sender
    @param toaddr: [string or list-of-strings] list of receivers (if string, then
                   receivers are separated by ',')
    @param usebcc: [bool] True for using Bcc in place of To
    @param subject: [string] subject of the email
    @param content: [string] content of the email
    @param html_content: [string] html version of the email
    @param html_images: [dict] dictionary of image id, image path
    @param header: [string] None for the default header
    @param footer: [string] None for the default footer
    @param ln: language
    @charset: [string] the content charset. By default is None which means
    to try to encode the email as ascii, then latin1 then utf-8.
    @param replytoaddr: [string or list-of-strings] to be used for the
                        reply-to header of the email (if string, then
                        receivers are separated by ',')
    @param attachments: list of paths of files to be attached. Alternatively,
        every element of the list could be a tuple: (filename, mimetype)
    @param bccaddr: [string or list-of-strings] to be used for BCC header of the email
                    (if string, then receivers are separated by ',')
    @return: forged email as an EmailMessage object"""
    from invenio_ext.template import render_template_to_string

    ln = default_ln(ln)
    if html_images is None:
        html_images = {}

    content = render_template_to_string(
        'mail_text.tpl',
        content=unicodifier(content),
        header=unicodifier(header),
        footer=unicodifier(footer)).encode('utf8')

    if isinstance(toaddr, list):
        toaddr = ','.join(toaddr)

    if isinstance(bccaddr, list):
        bccaddr = ','.join(bccaddr)

    if isinstance(replytoaddr, list):
        replytoaddr = ','.join(replytoaddr)

    toaddr = remove_temporary_emails(toaddr)

    headers = {}
    kwargs = {'to': [], 'cc': [], 'bcc': []}

    if replytoaddr:
        headers['Reply-To'] = replytoaddr
    if usebcc:
        headers['Bcc'] = bccaddr
        kwargs['bcc'] = toaddr.split(',') + bccaddr.split(',')
        kwargs['to'] = ['Undisclosed.Recipients:']
    else:
        kwargs['to'] = toaddr.split(',')
    headers['From'] = fromaddr
    headers['Date'] = formatdate(localtime=True)
    headers['User-Agent'] = 'Invenio %s at %s' % (cfg['CFG_VERSION'],
                                                  cfg['CFG_SITE_URL'])

    if html_content:
        html_content = render_template_to_string(
            'mail_html.tpl',
            content=unicodifier(html_content),
            header=unicodifier(html_header),
            footer=unicodifier(html_footer)).encode('utf8')

        msg_root = EmailMultiAlternatives(subject=subject,
                                          body=content,
                                          from_email=fromaddr,
                                          headers=headers,
                                          **kwargs)
        msg_root.attach_alternative(html_content, "text/html")

        # if not html_images:
        #    # No image? Attach the HTML to the root
        #    msg_root.attach(msg_text)
        # else:
        if html_images:
            # Image(s)? Attach the HTML and image(s) as children of a
            # "related" block
            msg_related = MIMEMultipart('related')
            # msg_related.attach(msg_text)
            for image_id, image_path in iteritems(html_images):
                attach_embed_image(msg_related, image_id, image_path)
            msg_root.attach(msg_related)
    else:
        msg_root = EmailMessage(subject=subject,
                                body=content,
                                from_email=fromaddr,
                                headers=headers,
                                **kwargs)

    if attachments:
        _mimes = MimeTypes(strict=False)
        for attachment in attachments:
            try:
                mime = None
                if type(attachment) in (list, tuple):
                    attachment, mime = attachment
                if mime is None:
                    # Automatic guessing of mimetype
                    mime = _mimes.guess_type(attachment)[0]
                if mime is None:
                    ext = _mimes.guess_extension(getContentType(attachment))
                    mime = _mimes.guess_type("foo" + ext)[0]
                if not mime:
                    mime = 'application/octet-stream'
                part = MIMEBase(*mime.split('/', 1))
                part.set_payload(open(attachment, 'rb').read())
                Encoders.encode_base64(part)
                part.add_header(
                    'Content-Disposition',
                    'attachment; filename="%s"' % os.path.basename(attachment))
                msg_root.attach(part)
            except:
                from invenio_ext.logging import register_exception
                register_exception(alert_admin=True,
                                   prefix="Can't attach %s" % attachment)

    return msg_root
Пример #35
0
def create_config(force=False, no_ssl=False):
    """
    Create Apache configuration files for this site, keeping previous
    files in a backup copy.
    """
    import os
    import pwd
    import pkg_resources
    import sys
    import shutil
    from flask import current_app
    from jinja2 import TemplateNotFound
    from invenio_ext.template import render_template_to_string
    from invenio_utils.text import wrap_text_in_a_box

    CFG_ETCDIR = current_app.config.get("CFG_ETCDIR", "")

    def get_context():
        conf = current_app.config

        # Apache vhost conf file is distro specific, so analyze needs:
        # Gentoo (and generic defaults):
        listen_directive_needed = True
        ssl_pem_directive_needed = False
        ssl_pem_path = CFG_ETCDIR + "/apache/ssl/apache.pem"
        ssl_crt_path = CFG_ETCDIR + "/apache/ssl/server.crt"
        ssl_key_path = CFG_ETCDIR + "/apache/ssl/server.key"
        vhost_ip_address_needed = False
        wsgi_socket_directive_needed = False
        # Debian:
        if os.path.exists(os.path.sep + "etc" + os.path.sep + "debian_version"):
            listen_directive_needed = False
            ssl_pem_directive_needed = True
            ssl_pem_path = "/etc/apache2/ssl/apache.pem"
            ssl_crt_path = "/etc/apache2/ssl/server.crt"
            ssl_key_path = "/etc/apache2/ssl/server.key"
        # RHEL/SLC:
        if os.path.exists(os.path.sep + "etc" + os.path.sep + "redhat-release"):
            listen_directive_needed = False
            ssl_crt_path = "/etc/pki/tls/certs/localhost.crt"
            ssl_key_path = "/etc/pki/tls/private/localhost.key"
            vhost_ip_address_needed = True
            wsgi_socket_directive_needed = True
        # maybe we are using non-standard ports?
        vhost_site_url = conf.get("CFG_SITE_URL").replace("http://", "")
        if vhost_site_url.startswith("https://"):
            # The installation is configured to require HTTPS for any
            # connection
            vhost_site_url = vhost_site_url.replace("https://", "")
        vhost_site_url_port = "80"
        vhost_site_secure_url = conf.get("CFG_SITE_SECURE_URL").replace("https://", "").replace("http://", "")
        vhost_site_secure_url_port = "443"
        if ":" in vhost_site_url:
            vhost_site_url, vhost_site_url_port = vhost_site_url.split(":", 1)
        if ":" in vhost_site_secure_url:
            vhost_site_secure_url, vhost_site_secure_url_port = vhost_site_secure_url.split(":", 1)
        if vhost_site_url_port != "80" or vhost_site_secure_url_port != "443":
            listen_directive_needed = True

        static_root = current_app.config["COLLECT_STATIC_ROOT"]
        if not os.path.exists(static_root):
            os.mkdir(static_root)

        def prepare_alias(filename):
            if os.path.isdir(os.path.join(static_root, filename)):
                return "/%s/" % (filename,)
            return "/%s" % (filename,)

        aliases = map(prepare_alias, os.listdir(static_root))

        apc1 = {
            "vhost_site_url_port": vhost_site_url_port,
            "servername": vhost_site_url,
            "serveralias": vhost_site_url.split(".")[0],
            "vhost_ip_address": vhost_ip_address_needed and _detect_ip_address() or "*",
            "wsgi_socket_directive_needed": wsgi_socket_directive_needed,
            "listen_directive_needed": listen_directive_needed,
            "aliases": aliases,
        }

        apc2 = {
            "vhost_site_url_port": vhost_site_secure_url_port,
            "servername": vhost_site_secure_url,
            "serveralias": vhost_site_secure_url.split(".")[0],
            "vhost_ip_address": vhost_ip_address_needed and _detect_ip_address() or "*",
            "wsgi_socket_directive_needed": wsgi_socket_directive_needed,
            "ssl_pem_directive": ssl_pem_directive_needed
            and "SSLCertificateFile %s" % ssl_pem_path
            or "#SSLCertificateFile %s" % ssl_pem_path,
            "ssl_crt_directive": ssl_pem_directive_needed
            and "#SSLCertificateFile %s" % ssl_crt_path
            or "SSLCertificateFile %s" % ssl_crt_path,
            "ssl_key_directive": ssl_pem_directive_needed
            and "#SSLCertificateKeyFile %s" % ssl_key_path
            or "SSLCertificateKeyFile %s" % ssl_key_path,
            "listen_directive_needed": listen_directive_needed,
            "aliases": aliases,
        }

        return [apc1, apc2]

    current_app.config.update(
        SYS_PREFIX=sys.prefix,
        CFG_RUNNING_AS_USER=pwd.getpwuid(os.getuid())[0],
        CFG_WSGIDIR=os.path.abspath(pkg_resources.resource_filename("invenio", "")),
    )

    apache_conf_dir = current_app.instance_path + os.sep + "apache"

    print(">>> Going to create Apache conf files...")
    conf_files = ["invenio-apache-vhost.conf", "invenio-apache-vhost-ssl.conf"]
    conf_files = conf_files[: 1 if no_ssl else 2]

    if not os.path.exists(apache_conf_dir):
        os.mkdir(apache_conf_dir)

    for local_file, context in zip(conf_files, get_context()[: 1 if no_ssl else 2]):
        print(">>> Writing %s ..." % local_file)

        try:
            apache_vhost_file = apache_conf_dir + os.sep + local_file
            if os.path.exists(apache_vhost_file):
                shutil.copy(apache_vhost_file, apache_vhost_file + ".OLD")

            with open(apache_vhost_file, "w") as f:
                out = render_template_to_string(local_file + ".tpl", os=os, **context)
                print(out, file=f)

        except TemplateNotFound:
            print("Could not find template %s".format(local_file), file=sys.stderr)

    print(
        wrap_text_in_a_box(
            """\
Apache virtual host configuration file(s) for your Invenio site
was(were) created.  Please check created file(s) and activate virtual
host(s).  For example, you can put the following include statements in
your httpd.conf:\n

%s

Please see the INSTALL file for more details.
    """
            % "\n\n".join(
                tuple(
                    map(
                        lambda x: "Include " + apache_conf_dir.encode("utf-8") + os.sep + x,
                        list(conf_files[: 1 if no_ssl else 2]),
                    )
                )
            )
        )
    )
    print(">>> Apache conf files created.")