def format_element(bfo):
    """
    List the 'featured' records
    """
    args = parse_url_string(bfo.user_info["uri"])
    journal_name = args["journal_name"]
    featured_records = get_featured_records(journal_name)
    lines = []
    for (recid, img_url) in featured_records:
        featured_record = BibFormatObject(recid)
        if bfo.lang == "fr":
            title = featured_record.field("246_1a")
            if title == "":
                # No French translation, get it in English
                title = featured_record.field("245__a")
        else:
            title = featured_record.field("245__a")

        lines.append(
            """
        <a href="%s/%s/%s?ln=%s" style="display:block">
            <img src="%s" alt="" width="100" class="phr" />
            %s
        </a>
        """
            % (CFG_SITE_URL, CFG_SITE_RECORD, recid, bfo.lang, img_url, title)
        )

    return "<br/><br/>".join(lines)
Beispiel #2
0
def perform_request_contact(req, ln, journal_name, verbose=0):
    """
    Display contact information
    """
    try:
        contact_page_template = get_journal_template('contact',
                                                     journal_name,
                                                     ln)
    except InvenioWebJournalTemplateNotFoundError as e:
        register_exception(req=req)
        return e.user_box(req)

    user_info = collect_user_info(req)
    temp_marc = '''<record>
                       <controlfield tag="001">0</controlfield>
                   </record>'''
    bfo = BibFormatObject(0,
                          ln=ln,
                          xml_record=temp_marc,
                          user_info=user_info)
    bfo.req = req
    html = format_with_format_template(contact_page_template,
                                       bfo)

    return html
def format_element(bfo):
    """
    List the 'featured' records
    """
    args = parse_url_string(bfo.user_info['uri'])
    journal_name = args["journal_name"]
    featured_records = get_featured_records(journal_name)
    lines = []
    for (recid, img_url) in featured_records:
        featured_record = BibFormatObject(recid)
        if bfo.lang == 'fr':
            title = featured_record.field('246_1a')
            if title == '':
                # No French translation, get it in English
                title = featured_record.field('245__a')
        else:
            title = featured_record.field('245__a')

        lines.append('''
        <a href="%s/%s/%s?ln=%s" style="display:block">
            <img src="%s" alt="" width="100" class="phr" />
            %s
        </a>
        ''' % (CFG_SITE_URL, CFG_SITE_RECORD, recid, bfo.lang, img_url, title))

    return '<br/><br/>'.join(lines)
Beispiel #4
0
def perform_request_index(req, journal_name, issue_number, ln,
                          category, editor=False, verbose=0):
    """
    Central logic function for index pages.
    Brings together format templates and MARC rules from the config, with
    the requested index page, given by the url parameters.
    From config:
        - page template for index pages -> formatting
        - MARC rule list -> Category Navigation
        - MARC tag used for issue numbers -> search (later in the format
          elements)
    Uses BibFormatObject and format_with_format_template to produce the
    required HTML.
    """
    current_issue = get_current_issue(ln, journal_name)
    if not get_release_datetime(issue_number, journal_name):
        # Unreleased issue. Display latest released issue?
        unreleased_issues_mode = get_unreleased_issue_hiding_mode(journal_name)
        if not editor and \
               (unreleased_issues_mode == 'all' or \
                (unreleased_issues_mode == 'future' and \
                 issue_is_later_than(issue_number, current_issue))):
            redirect_to_url(req, "%s/journal/%s/%s/%s?ln=%s" % \
                            (CFG_SITE_URL,
                             journal_name,
                             current_issue.split('/')[1],
                             current_issue.split('/')[0],
                             ln))
    try:
        index_page_template = get_journal_template('index',
                                                   journal_name,
                                                   ln)
    except InvenioWebJournalTemplateNotFoundError as e:
        register_exception(req=req)
        return e.user_box(req)

    temp_marc = '''<record>
                        <controlfield tag="001">0</controlfield>
                    </record>'''
    # create a record and get HTML back from bibformat
    user_info = collect_user_info(req)
    bfo = BibFormatObject(0, ln=ln, xml_record=temp_marc,
                          user_info=user_info)
    bfo.req = req
    verbosity = 0
    if editor:
        # Increase verbosity only for editors/admins
        verbosity = verbose

    html = format_with_format_template(index_page_template,
                                       bfo,
                                       verbose=verbosity)
    return html
Beispiel #5
0
def perform_request_search(req, journal_name, ln,
                           archive_issue, archive_select,
                           archive_date, archive_search, verbose=0):
    """
    Logic for the search / archive page.
    """
    try:
        search_page_template = get_journal_template('search',
                                                    journal_name,
                                                    ln)
    except InvenioWebJournalTemplateNotFoundError as e:
        register_exception(req=req)
        return e.user_box(req)

    if archive_select == "False" and archive_search == "False":
        temp_marc = '''<record>
                            <controlfield tag="001">0</controlfield>
                        </record>'''

        user_info = collect_user_info(req)
        bfo = BibFormatObject(0,
                              ln=ln,
                              xml_record=temp_marc,
                              user_info=user_info)
        bfo.req = req
        html = format_with_format_template(search_page_template,
                                           bfo,
                                           verbose=verbose)
        return html

    elif archive_select == "Go":
        redirect_to_url(req, "%s/journal/%s/%s/%s?ln=%s" % (CFG_SITE_URL,
                                                            journal_name,
                                                            archive_issue.split('/')[1],
                                                            archive_issue.split('/')[0],
                                                            ln))
    elif archive_search == "Go":
        try:
            archive_issue_time = datetime.datetime(*time.strptime(archive_date, "%d/%m/%Y")[0:5])
            archive_issue = datetime_to_issue(archive_issue_time, journal_name)
            if not archive_issue:
                archive_issue = get_current_issue(ln, journal_name)
        except ValueError:
            archive_issue = get_current_issue(ln, journal_name)
        redirect_to_url(req, "%s/journal/%s/%s/%s?ln=%s" % (CFG_SITE_URL,
                                                            journal_name,
                                                            archive_issue.split('/')[1],
                                                            archive_issue.split('/')[0],
                                                            ln))
Beispiel #6
0
def schemaorg_type(recid=None, bfo=None):
    if recid:
        from invenio.modules.formatter.engine import BibFormatObject
        bfo = BibFormatObject(recid)

    if bfo:
        SCHEMAORG_MAP = current_app.config['SCHEMAORG_MAP']
        collections = bfo.fields('980__')
        for c in collections:
            a = c.get('a', None)
            b = c.get('b', None)
            res = SCHEMAORG_MAP.get(b if b else a, None)
            if res:
                return res
    return 'http://schema.org/CreativeWork'
Beispiel #7
0
def schemaorg_type(recid=None, bfo=None):
    if recid:
        from invenio.modules.formatter.engine import BibFormatObject
        bfo = BibFormatObject(recid)

    if bfo:
        SCHEMAORG_MAP = current_app.config['SCHEMAORG_MAP']
        collections = bfo.fields('980__')
        for c in collections:
            a = c.get('a', None)
            b = c.get('b', None)
            res = SCHEMAORG_MAP.get(b if b else a, None)
            if res:
                return res
    return 'http://schema.org/CreativeWork'
Beispiel #8
0
    def answer(self, req, user_info, of, cc, colls_to_search, p, f,
               search_units, ln):
        """
        Answer question given by context.

        Return (relevance, html_string) where relevance is integer
        from 0 to 100 indicating how relevant to the question the
        answer is (see C{CFG_WEBSEARCH_SERVICE_MAX_SERVICE_ANSWER_RELEVANCE} for details) ,
        and html_string being a formatted answer.
        """
        if f:
            return (0, '')

        words = [unit[1].lower() for unit in search_units if unit[2] == ""]

        if not words:
            return (0, '')

        _ = gettext_set_language(ln)
        if not _("weather").lower() in words and \
               not "météo" in words and \
               not "meteo" in words:
            return (0, '')

        bfo = BibFormatObject(0)
        if meteoblue_widget_available_p:
            output = bfe_webjournal_widget_weather_meteoblue.format_element(
                bfo)
        else:
            output = bfe_webjournal_widget_weather.format_element(
                bfo, display_weather_icon='true')
        if not output:
            return (0, '')

        return (100, output)
Beispiel #9
0
def get_widget_html(language, max_photos, collections, separator, ln):
    """
    Returns the content of the widget
    """
    latest_photo_ids = perform_request_search(c=collections,
                                              rg=max_photos,
                                              of='id')
    images_urls = []
    for recid in latest_photo_ids[:max_photos]:
        try:
            photo_record = BibFormatObject(recid)
        except:
            # todo: Exception, no photo in this selection
            continue

        if language == "fr":
            try:
                title = photo_record.fields('246_1a', escape=1)[0]
            except KeyError:
                try:
                    title = photo_record.fields('245__a', escape=1)[0]
                except:
                    title = ""
        else:
            try:
                title = photo_record.fields('245__a', escape=1)[0]
            except KeyError:
                # todo: exception, picture with no title
                title = ""

        if CFG_CERN_SITE and photo_record.fields('8567_'):
            # Get from 8567_
            dfs_images = photo_record.fields('8567_')
            for image_block in dfs_images:
                if image_block.get("y", '') == "Icon":
                    if image_block.get("u", '').startswith("http://"):
                        images_urls.append((recid, image_block["u"], title))
                        break  # Just one image per record

        else:
            # Get from 8564_
            images = photo_record.fields('8564_')
            for image_block in images:
                if image_block.get("x", '').lower() == "icon":
                    if image_block.get("q", '').startswith("http://"):
                        images_urls.append((recid, image_block["q"], title))
                        break  # Just one image per record

    # Build output
    html_out = separator.join([
        '<a href="%s/%s/%i?ln=%s"><img class="phr" width="100" height="67" src="%s"/>%s</a>'
        % (CFG_SITE_URL, CFG_SITE_RECORD, recid, ln, photo_url, title)
        for (recid, photo_url, title) in images_urls
    ])

    return html_out
Beispiel #10
0
def format_element(bfo):
    """
    Prints the list of papers containing the dataset by title.
    """

    from invenio.modules.formatter.engine import BibFormatObject
    from invenio.config import CFG_BASE_URL, CFG_SITE_RECORD

    parent_recid = bfo.field("786__w")
    bfo_parent = BibFormatObject(parent_recid)

    title = bfo_parent.field("245__a")
    url = CFG_BASE_URL + '/' + CFG_SITE_RECORD + '/' + str(bfo_parent.recID)

    out = "This dataset complements the following publication: <br />"
    out += "<a href=\"" + url + "\">" + title + "</a>"

    return out
Beispiel #11
0
def format_element(bfo):
    """
    Prints the list of papers containing the dataset by title.
    """
    
    from invenio.modules.formatter.engine import BibFormatObject
    from invenio.config import CFG_BASE_URL, CFG_SITE_RECORD

    parent_recid = bfo.field("786__w")
    bfo_parent = BibFormatObject(parent_recid)
    
    title = bfo_parent.field("245__a")
    url = CFG_BASE_URL + '/' + CFG_SITE_RECORD + '/' + str(bfo_parent.recID) 

    out = "This dataset complements the following publication: <br />"
    out += "<a href=\"" + url + "\">" + title + "</a>" 
    
    return out
Beispiel #12
0
def perform_request_popup(req, ln, journal_name, record):
    """
    Display the popup window
    """
    try:
        popup_page_template = get_journal_template('popup',
                                                   journal_name,
                                                   ln)
    except InvenioWebJournalTemplateNotFoundError as e:
        register_exception(req=req)
        return e.user_box(req)

    user_info = collect_user_info(req)
    bfo = BibFormatObject(record, ln=ln, user_info=user_info)
    bfo.req = req
    html = format_with_format_template(popup_page_template,
                                       bfo)

    return html
Beispiel #13
0
def _eval_bibformat(ctx, recID, template_code):
    """
    Bridge between BibFormat and XSL stylesheets.

    Can be used in that way in XSL stylesheet (provided
    ``xmlns:fn="http://cdsweb.cern.ch/bibformat/fn"`` has been declared)::

        <xsl:value-of select="fn:eval_bibformat(marc:controlfield[@tag='001'],
                              '&lt;BFE_SERVER_INFO var=&quot;recurl&quot;>')"/>

    if recID is string, value is converted to int
    if recID is Node, first child node (text node) is taken as value
    template_code is evaluated as a format template piece of code. '<'
    and '"' need to be escaped with '&lt;' and '&quot;'

    :param ctx: context as passed by lxml
    :param recID: record ID
    :param template_code: the code calling a BFE_ as it would be used in
                          format template
    :return: the evaluated call to a format template (usually a call to a
             format element)
    :rtype: str

    """
    from invenio.modules.formatter.engine import format_with_format_template, \
        BibFormatObject
    try:
        if isinstance(recID, str):
            recID_int = int(recID)
        elif isinstance(recID, (int, long)):
            recID_int = recID
        elif isinstance(recID, list):
            recID = recID[0]
            if isinstance(recID, str):
                recID_int = int(recID)
            else:
                recID_int = int(recID.text)
        else:
            recID_int = int(recID.text)

        bfo = BibFormatObject(recID_int)
        out = format_with_format_template(None,
                                          bfo,
                                          verbose=0,
                                          format_template_code=template_code)
        return out[0]
    except Exception:
        current_app.logger.exception(
            "Error during formatting function evaluation.")
        return ''
def get_widget_html(language, max_photos, collections, separator, ln):
    """
    Returns the content of the widget
    """
    latest_photo_ids = perform_request_search(c=collections,
                                              rg=max_photos,
                                              of='id')
    images_urls = []
    for recid in latest_photo_ids[:max_photos]:
        try:
            photo_record = BibFormatObject(recid)
        except:
            # todo: Exception, no photo in this selection
            continue

        if language == "fr":
            try:
                title = photo_record.fields('246_1a', escape=1)[0]
            except KeyError:
                try:
                    title = photo_record.fields('245__a', escape=1)[0]
                except:
                    title = ""
        else:
            try:
                title = photo_record.fields('245__a', escape=1)[0]
            except KeyError:
                # todo: exception, picture with no title
                title = ""

        if CFG_CERN_SITE and photo_record.fields('8567_'):
            # Get from 8567_
            dfs_images = photo_record.fields('8567_')
            for image_block in dfs_images:
                if image_block.get("y", '') == "Icon":
                    if image_block.get("u", '').startswith("http://"):
                        images_urls.append((recid, image_block["u"], title))
                        break # Just one image per record

        else:
            # Get from 8564_
            images = photo_record.fields('8564_')
            for image_block in images:
                if image_block.get("x", '').lower() == "icon":
                    if image_block.get("q", '').startswith("http://"):
                        images_urls.append((recid, image_block["q"], title))
                        break # Just one image per record

    # Build output
    html_out = separator.join(['<a href="%s/%s/%i?ln=%s"><img class="phr" width="100" height="67" src="%s"/>%s</a>' % (CFG_SITE_URL, CFG_SITE_RECORD, recid, ln, photo_url, title) for (recid, photo_url, title) in images_urls])

    return html_out
def _get_breaking_news(lang, journal_name):
    """
    Gets the 'Breaking News' articles that are currently active according to
    start and end dates.
    """
    # CERN Bulletin only
    if not journal_name.lower() == 'cernbulletin':
        return ''
    # Look for active breaking news
    breaking_news_recids = [recid for recid in search_pattern(p='980__a:BULLETINBREAKING') \
                            if record_exists(recid) == 1]
    today = time.mktime(time.localtime())
    breaking_news = ""
    for recid in breaking_news_recids:
        temp_rec = BibFormatObject(recid)
        try:
            end_date = time.mktime(time.strptime(temp_rec.field("925__b"),
                                                 "%m/%d/%Y"))
        except:
            end_date = time.mktime(time.strptime("01/01/1970", "%m/%d/%Y"))
        if end_date < today:
            continue
        try:
            start_date = time.mktime(time.strptime(temp_rec.field("925__a"),
                                                   "%m/%d/%Y"))
        except:
            start_date = time.mktime(time.strptime("01/01/2050", "%m/%d/%Y"))
        if start_date > today:
            continue
        publish_date = temp_rec.field("269__c")
        if lang == 'fr':
            title = temp_rec.field("246_1a")
        else:
            title = temp_rec.field("245__a")
        breaking_news += '''
<h2 class="%s">%s<br/>
    <strong>
        <a href="%s/journal/popup?name=%s&amp;type=breaking_news&amp;record=%s&amp;ln=%s" target="_blank">%s</a>
    </strong>
</h2>
''' % ("", publish_date, CFG_SITE_URL, journal_name, recid, lang, title)
    if breaking_news:
        breaking_news = '<li>%s</li>' % breaking_news

    return breaking_news
Beispiel #16
0
def hepdata_cite_as(bfo):
    """
    HepData format example:
        Cite as: The ATLAS Collaboration (2013) HepData, doi: 10.1234/123456
    """

    from invenio.modules.formatter.engine import BibFormatObject

    colls = []
    for coll in bfo.fields("710__g"):
        if coll not in colls:
            colls.append(coll)

    parent_recid = bfo.field("786__w")
    bfo_parent = BibFormatObject(parent_recid)
    year = get_year(bfo_parent)
    if year == None:
        year = 0

    publisher = bfo.field("520__9")
    if publisher == 'HEPDATA':
        publisher = 'HepData'

    pid_type = bfo.field("0247_2")
    pid = bfo.field("0247_a")

    out = ''
    out += ("<b>Cite as: </b>")
    out += str(colls[0])
    out += ' ( ' + str(year) + ' ) '
    out += publisher + ', '

    if pid_type == 'DOI':
        out += '<a href="http://doi.org/' + pid + '" target="_blank" > http://doi.org/' + pid + '</a>'
    elif pid_type == 'HDL':
        out += '<a href="http://hdl.handle.net/' + pid + '" target="_blank" > http://hdl.handle.net/' + pid + '</a>'
    elif pid_type == '':
        out += '[no persistent identifier assigned]'

    return out
def _get_breaking_news(lang, journal_name):
    """
    Gets the 'Breaking News' articles that are currently active according to
    start and end dates.
    """
    # CERN Bulletin only
    if not journal_name.lower() == 'cernbulletin':
        return ''
    # Look for active breaking news
    breaking_news_recids = [recid for recid in search_pattern(p='980__a:BULLETINBREAKING') \
                            if record_exists(recid) == 1]
    today = time.mktime(time.localtime())
    breaking_news = ""
    for recid in breaking_news_recids:
        temp_rec = BibFormatObject(recid)
        try:
            end_date = time.mktime(time.strptime(temp_rec.field("925__b"),
                                                 "%m/%d/%Y"))
        except:
            end_date = time.mktime(time.strptime("01/01/1970", "%m/%d/%Y"))
        if end_date < today:
            continue
        try:
            start_date = time.mktime(time.strptime(temp_rec.field("925__a"),
                                                   "%m/%d/%Y"))
        except:
            start_date = time.mktime(time.strptime("01/01/2050", "%m/%d/%Y"))
        if start_date > today:
            continue
        publish_date = temp_rec.field("269__c")
        if lang == 'fr':
            title = temp_rec.field("246_1a")
        else:
            title = temp_rec.field("245__a")
        breaking_news += '''
<h2 class="%s">%s<br/>
    <strong>
        <a href="%s/journal/popup?name=%s&amp;type=breaking_news&amp;record=%s&amp;ln=%s" target="_blank">%s</a>
    </strong>
</h2>
''' % ("", publish_date, CFG_SITE_URL, journal_name, recid, lang, title)
    if breaking_news:
        breaking_news = '<li>%s</li>' % breaking_news

    return breaking_news
Beispiel #18
0
def format_element(bfo,
                   limit,
                   separator='; ',
                   extension='[...]',
                   print_links="yes",
                   print_affiliations='no',
                   affiliation_prefix=' (',
                   affiliation_suffix=')',
                   print_affiliation_first='no',
                   interactive="no",
                   highlight="no",
                   affiliations_separator=" ; ",
                   name_last_first="yes",
                   collaboration="yes",
                   id_links="no",
                   markup="html",
                   link_extension="no",
                   suffix=''):
    """
    Prints the list of authors of a record.

    @param limit the maximum number of authors to display
    @param separator the separator between authors.
    @param extension a text printed if more authors than 'limit' exist
    @param print_links if yes, prints the authors as HTML link to their publications
    @param print_affiliations if yes, make each author name followed by its affiliation
    @param affiliation_prefix prefix printed before each affiliation
    @param affiliation_suffix suffix printed after each affiliation
    @param print_affiliation_first if 'yes', affiliation is printed before the author
    @param interactive if yes, enable user to show/hide authors when there are too many (html + javascript)
    @param highlight highlights authors corresponding to search query if set to 'yes'
    @param affiliations_separator separates affiliation groups
    @param name_last_first if yes (default) print last, first  otherwise first last
    @param collaboration if yes (default) uses collaboration name in place of long author list, if available
    @param id_links if yes (default = no) prints link based on INSPIRE IDs if available - only used if print_links = yes
    @param markup html (default) or latex controls small markup differences
    @param link_extension if 'yes' link the extension to the detailed
    record page

    """
    from urllib import quote
    from cgi import escape
    import re
    from invenio.base.i18n import gettext_set_language
    from invenio.config import CFG_BASE_URL, CFG_SITE_RECORD
    from invenio.modules.formatter.engine import BibFormatObject

    _ = gettext_set_language(bfo.lang)  # load the right message language

    #regex for parsing last and first names and initials
    re_last_first = re.compile(
        '^(?P<last>[^,]+)\s*,\s*(?P<first_names>[^\,]*)(?P<extension>\,?.*)$')
    re_initials = re.compile(r'(?P<initial>\w)(\w+|\.)\s*')
    re_coll = re.compile(r'\s*collaborations?', re.IGNORECASE)

    bibrec_id = bfo.control_field("001")
    authors = []
    lastauthor = ''

    # HepData and only-INSPIRE data records inherit the list of authors from the original paper
    if (bfo.field("520__9") == "HEPDATA") or (bfo.field("520__9")
                                              == "INSPIRE"):
        parent_recid = bfo.field("786__w")
        bfo_parent = BibFormatObject(int(parent_recid))

        authors = []
        authors_1 = bfo_parent.fields('100__', repeatable_subfields_p=True)
        authors_2 = bfo_parent.fields('700__', repeatable_subfields_p=True)
    # other datasources should have a list of authors
    else:
        authors = []
        authors_1 = bfo.fields('100__', repeatable_subfields_p=True)
        authors_2 = bfo.fields('700__', repeatable_subfields_p=True)

    authors.extend(authors_1)
    authors.extend(authors_2)

    # If there are no author check for corporate author in 110__a field
    if len(authors) == 0:
        authors = bfo.fields('110__', repeatable_subfields_p=True)
        # For corporate authors we don't want to reverse names order
        name_last_first = 'yes'
        # And we don't want to create links
        print_links = 'no'

    # Keep real num of authors. fix + affiliations_separator.join(author['u']) + \
    nb_authors = len(authors)

    # Limit num of authors, so that we do not process
    # the authors that will not be shown. This can only
    # be done in non-interactive mode, as interactive mode
    # allows to show all of them.
    if limit.isdigit() and nb_authors > int(limit) \
           and interactive != "yes":
        if bfo.field('710g'):  # check for colln note
            authors = authors[:1]
        else:

            authors = authors[:int(limit)]

    # Process authors to add link, affiliation and highlight
    for author in authors:

        if author.has_key('a'):
            author['a'] = author['a'][0]  # There should not be
            # repeatable subfields here.
            if highlight == 'yes':
                from invenio import bibformat_utils
                author['a'] = bibformat_utils.highlight(
                    author['a'], bfo.search_pattern)

            #check if we need to reverse last, first
            #we don't try to reverse it if it isn't stored with a comma.
            first_last_match = re_last_first.search(author['a'])
            author['display'] = author['a']

            if name_last_first.lower() == "no":
                if first_last_match:
                    author['display'] = first_last_match.group('first_names') + \
                                        ' ' + \
                                        first_last_match.group('last') + \
                                        first_last_match.group('extension')

            #for latex we do initials only  (asn assume first last)
            if markup == 'latex':
                if first_last_match:
                    first = re_initials.sub('\g<initial>.~', \
                                        first_last_match.group('first_names'))
                    author['display'] = first  + \
                                        first_last_match.group('last') + \
                                        first_last_match.group('extension')

            if print_links.lower() == "yes":

                # if there is an ID, search using that.
                id_link = ''
                if id_links == "yes" and author.has_key('i'):
                    author['i'] = author['i'][0]  #possible to have more IDs?
                    id_link = '<a class="authoridlink" href="' + \
                              CFG_BASE_URL + \
                              '/search?' + \
                              'ln='+ bfo.lang + \
                              '&amp;p=100__i' + escape(':' + author['i']) + \
                              '+or+700__i' + escape(':' + author['i']) +\
                              '">'+escape("(ID Search)") + '</a> '


                author['display'] = '<a class="authorlink" href="' + \
                                    CFG_BASE_URL + \
                                    '/author/'+ quote(author['a']) + \
                                    '?recid=' + bibrec_id + \
                                    '&amp;ln='+ bfo.lang + \
                                    '">' + escape(author['display'])+'</a>' + \
                                    id_link

        if print_affiliations == "yes":
            if author.has_key('e'):
                author['e'] = affiliation_prefix + \
                              affiliations_separator.join(author['e']) + \
                              affiliation_suffix

            if author.has_key('u'):
                author['ilink'] = ['<a class="afflink" href="' + \
                                   CFG_BASE_URL + '/search?cc=Institutions&amp;p=institution:'+ \
                                   quote('"' + string + '"') + \
                                   '&amp;ln=' + bfo.lang + \
                                   '">' + \
                                   string.lstrip() + \
                                   '</a>' for string in author['u']]
                author['u'] = affiliation_prefix + \
                              affiliations_separator.join(author['ilink']) + \
                              affiliation_suffix

#
#  Consolidate repeated affiliations
#
    last = ''
    authors.reverse()
    for author in authors:
        if not author.has_key('u'):
            author['u'] = ''
        #print 'this->'+ author['a']+'\n'
        if last == author['u']:
            author['u'] = ''
        else:
            last = author['u']

    authors.reverse()

    # Flatten author instances
    if print_affiliations == 'yes':
        #      100__a (100__e)  700__a (100__e) (100__u)
        if print_affiliation_first.lower() != 'yes':
            authors = [
                author.get('display', '') + author.get('e', '') +
                author.get('u', '') for author in authors
            ]

        else:
            authors = [
                author.get('u', '') + author.get('display', '')
                for author in authors
            ]

    else:
        authors = [author.get('display', '') for author in authors]

    # link the extension to detailed record
    if link_extension == 'yes' and interactive != 'yes':
        extension = '<a class="authorlink" href="' +  \
                    CFG_BASE_URL + '/' + CFG_SITE_RECORD + '/' + str(bfo.recID) + '">' + \
                    extension + '</a>'

    # Detect Collaborations:
    if collaboration == "yes":
        colls = []
        for coll in bfo.fields("710__g"):
            if coll not in colls:
                colls.append(coll)
    else:
        colls = []
    if colls:
        short_coll = False
        colls = [re_coll.sub('', coll) for coll in colls]
        if print_links.lower() == "yes":
            colls = [
                '<a class="authorlink" href="' + CFG_BASE_URL + '/search' +
                '?p=collaboration:' + quote("'" + coll + "'") + '&amp;ln=' +
                bfo.lang + '">' + escape(coll) + '</a>' for coll in colls
            ]

        coll_display = " and ".join(colls)
        if not coll_display.endswith("aboration"):
            coll_display += " Collaboration"
            if len(colls) > 1:
                coll_display += 's'
        if nb_authors > 1:
            if markup == 'latex':
                coll_display =  authors[0] + extension + "  [" + \
                               coll_display + "]"
            elif interactive == "yes":
                coll_display += " (" + authors[0] + " "
                extension += ")"
            else:  #html
                coll_display += " (" + authors[0] + extension + ")"
        elif nb_authors == 1:
            short_coll = True
            if markup == 'latex':
                coll_display = authors[0] + " [" + coll_display + "]"
            else:  #html
                coll_display += " (" + authors[0] + " for the collaboration)"
        elif nb_authors == 0:
            short_coll = True
            if markup == 'latex':
                coll_display = "[" + coll_display + "]"

    # Start outputting, depending on options and number of authors
    if colls and (interactive != "yes" or short_coll):
        return coll_display

    if limit.isdigit() and nb_authors > int(limit) and interactive != "yes":
        if markup == 'latex':
            lastauthor = authors.pop()
            lastauthor = ' and ' + lastauthor
            limit = int(limit) - 1

        return separator.join(authors[:int(limit)]) + lastauthor + \
               extension

    elif interactive == "yes" and (
        (colls and not short_coll) or
        (limit.isdigit() and nb_authors > int(limit))):
        out = '''
        <script>
        function toggle_authors_visibility(){
            var more = document.getElementById('more');
            var link = document.getElementById('link');
            var extension = document.getElementById('extension');
            if (more.style.display=='none'){
                more.style.display = '';
                extension.style.display = 'none';
                link.innerHTML = "%(show_less)s"
            } else {
                more.style.display = 'none';
                extension.style.display = '';
                link.innerHTML = "%(show_more)s"
            }
            link.style.color = "rgb(204,0,0);"
        }

        function set_up(){
            var extension = document.getElementById('extension');
            extension.innerHTML = '%(extension)s';
            toggle_authors_visibility();
        }

        </script>
        ''' % {
            'show_less':
            _("Hide"),
            'show_more':
            _("Show all %(x_num_of_authors)i authors",
              x_num_of_authors=nb_authors),
            'extension':
            extension
        }

        #        out += '<a name="show_hide" />'
        if colls:
            show = coll_display
            more = separator + separator.join(authors[1:]) + ')'
        else:
            show = separator.join(authors[:int(limit)])
            more = separator.join(authors[int(limit):len(authors)])

        out += show
        out += ' <span id="more" style="">' + more + '</span>'
        out += ' <span id="extension"></span>'
        out += ' <small><i><a id="link" href="#"' + \
               ' style="color:green;background:white;" onclick="toggle_authors_visibility()" ' + \
               ' style="color:rgb(204,0,0);"></a></i></small>'
        out += '<script>set_up()</script>'
        return out
    elif nb_authors > 0:
        if markup == 'latex' and nb_authors > 1:
            lastauthor = authors.pop()
            lastauthor = ' and ' + lastauthor
        output = separator.join(authors) + lastauthor
        # remove the dot from the end of authors list when the suffix starts with dot
        # (to avoid two consecutive dots)
        if suffix and output and output[-1] == suffix[0] == '.':
            output = output[:-1]
        return output
def format_element(bfo,
                   number_of_featured_articles="1",
                   number_of_articles_with_image="3",
                   new_articles_first='yes',
                   image_px_width="300",
                   small_image_px_width="200",
                   subject_to_css_class_kb="WebJournalSubject2CSSClass",
                   link_image_to_article='yes',
                   image_alignment='left'):
    """
    Creates an overview of all the articles of a certain category in one
    specific issue.

    Note the following:
    <ul>
    <li>The element consider only the latest issue: when viewing
    archives of your journal, readers will see the newest articles of
    the latest issue, not the ones of the issue they are looking
    at</li>

    <li>This is not an index of the articles of the latest issue: it
    display only <b>new</b> articles, that is articles that have never
    appeared in a previous issue</li>

    <li>This element produces a table-based layout, in order to have a
    more or less readable HTML alert when sent some Email clients
    (Outlook 2007)</li>

    <li>When producing the HTML output of images, this element tries to
    insert the width and height attributes to the img tag: this is
    necessary in order to produce nice HTML alerts. This dimension
    therefore overrides any dimension defined in the CSS. The Python
    Image Library (PIL) should be installed for this element to
    recognize the size of images.</li>
    </ul>

    @param number_of_featured_articles: the max number of records with emphasized title
    @param number_of_articles_with_image: the max number of records for which their image is displayed
    @param new_articles_first: if 'yes', display new articles before other articles
    @param image_px_width: (integer) width of first image featured on this page
    @param small_image_px_width: (integer) width of small images featured on this page
    @param subject_to_css_class_kb: knowledge base that maps 595__a to a CSS class
    @param link_image_to_article: if 'yes', link image (if any) to article
    @param image_alignment: 'left', 'center' or 'right'. To help rendering in Outlook.
    """
    args = parse_url_string(bfo.user_info['uri'])
    journal_name = args["journal_name"]
    this_issue_number = args["issue"]
    category_name = args["category"]
    verbose = args["verbose"]
    ln = bfo.lang
    _ = gettext_set_language(ln)

    if image_px_width.isdigit():
        image_px_width = int(image_px_width)
    else:
        image_px_width = None
    if small_image_px_width.isdigit():
        small_image_px_width = int(small_image_px_width)
    else:
        small_image_px_width = None

    # We want to put emphasis on the n first articles (which are not
    # new)
    if number_of_featured_articles.isdigit():
        number_of_featured_articles = int(number_of_featured_articles)
    else:
        number_of_featured_articles = 0

    # Only n first articles will display images
    if number_of_articles_with_image.isdigit():
        number_of_articles_with_image = int(number_of_articles_with_image)
    else:
        number_of_articles_with_image = 0

    # Help image alignement without CSS, to have better rendering in Outlook
    img_align = ''
    if image_alignment:
        img_align = 'align="%s"' % image_alignment

    # Try to get the page from cache. Only if issue is older or equal
    # to latest release.
    latest_released_issue = get_current_issue(ln, journal_name)
    if verbose == 0 and not issue_is_later_than(this_issue_number,
                                                latest_released_issue):
        cached_html = get_index_page_from_cache(journal_name, category_name,
                                                this_issue_number, ln)
        if cached_html:
            return cached_html

    out = '<table border="0" cellpadding="0" cellspacing="0">'
    # Get the id list
    ordered_articles = get_journal_articles(
        journal_name,
        this_issue_number,
        category_name,
        newest_first=new_articles_first.lower() == 'yes')
    new_articles_only = False
    if ordered_articles.keys() and max(ordered_articles.keys()) < 0:
        # If there are only new articles, don't bother marking them as
        # new
        new_articles_only = True

    order_numbers = ordered_articles.keys()
    order_numbers.sort()
    img_css_class = "featuredImageScale"

    for order_number in order_numbers:
        for article_id in ordered_articles[order_number]:
            # A record is considered as new if its position is
            # negative and there are some non-new articles
            article_is_new = (order_number < 0 and not new_articles_only)

            temp_rec = BibFormatObject(article_id)
            title = ''
            if ln == "fr":
                title = temp_rec.field('246_1a')
                if title == '':
                    title = temp_rec.field('245__a')
            else:
                title = temp_rec.field('245__a')
                if title == '':
                    title = temp_rec.field('246_1a')

            # Get CSS class (if relevant)
            notes = temp_rec.fields('595__a')
            css_classes = [temp_rec.kb(subject_to_css_class_kb, note, None) \
                           for note in notes]
            css_classes = [css_class for css_class in css_classes \
                           if css_class is not None]

            if article_is_new:
                css_classes.append('new')

            # Maybe we want to force image to appear?
            display_image_on_index = False
            if 'display_image_on_index' in notes:
                display_image_on_index = True

            # Build generic link to this article
            article_link = make_journal_url(bfo.user_info['uri'], {
                'recid': str(article_id),
                'ln': bfo.lang
            })

            # Build the "more" link
            more_link = '''<a class="readMore" title="link to the article" href="%s"> &gt;&gt; </a>
                        ''' % (article_link)

            # If we should display an image along with the text,
            # prepare it here
            img = ''
            if (number_of_articles_with_image > 0 and \
                   not article_is_new) or display_image_on_index:
                img = _get_feature_image(temp_rec, ln)
                if img != "":
                    # Now we will try to identify image size in order
                    # to resize it in the HTML for a nicer rendering
                    # of the HTML alert in email clients (Outlook wants
                    # both height and width)
                    img_width = None
                    img_height = None
                    small_img_width = None
                    small_img_height = None
                    width_and_height = ''
                    if PIL_imported:
                        try:
                            local_img = os.path.join(CFG_TMPDIR,
                                                     'webjournal_' + \
                                                     ''.join([char for char in img \
                                                              if char.isalnum()]))
                            if len(local_img) > 255:
                                # Shorten to 255 chars
                                local_img = local_img[0:100] + '_' + local_img[
                                    156:]
                            if not os.path.exists(local_img):
                                # Too bad, must download entire image for PIL
                                content_type = get_content_type(img)
                                if 'image' in content_type:
                                    (local_img, headers) = urllib.urlretrieve(
                                        img, local_img)
                                    img_file = Image.open(
                                        local_img
                                    )  # IOError if not readable image
                                else:
                                    raise IOError('Not an image')
                            else:
                                img_file = Image.open(
                                    local_img)  # IOError if not readable image
                        except IOError as e:
                            pass
                        else:
                            orig_img_width = img_file.size[0]
                            orig_img_height = img_file.size[1]
                            # Then scale according to user-defined width
                            ## First image
                            ratio = float(orig_img_width) / image_px_width
                            img_width = image_px_width
                            img_height = int(orig_img_height / ratio)
                            ## Other smaller images
                            ratio = float(
                                orig_img_width) / small_image_px_width
                            small_img_width = small_image_px_width
                            small_img_height = int(orig_img_height / ratio)

                    # Note that we cannot reuse the nice phl, ph and
                    # phr classes to put a frame around the image:
                    # this is not supported in Outlook 2007 when HTML
                    # alert is sent.
                    if not img_css_class == "featuredImageScale":
                        # Not first image: display smaller
                        img_width = small_img_width
                        img_height = small_img_height

                    if img_width and img_height:
                        width_and_height = 'width="%i" height="%i"' % \
                                           (img_width, img_height)
                    img = '<img alt="" class="%s" src="%s" %s %s/>' % \
                          (img_css_class, img, img_align, width_and_height)
                    number_of_articles_with_image -= 1

                    # Next images will be displayed smaller
                    img_css_class = "featuredImageScaleSmall"

            # Determine size of the title
            header_tag_size = '3'
            if number_of_featured_articles > 0 and \
                   not article_is_new:
                # n first articles are especially featured
                header_tag_size = '2'
                number_of_featured_articles -= 1

            # Finally create the output. Two different outputs
            # depending on if we have text to display or not
            text = ''
            if not article_is_new:
                text = _get_feature_text(temp_rec, ln)
            # Link image to article if wanted
            if link_image_to_article.lower() == 'yes':
                img = create_html_link(urlbase=article_link,
                                       link_label=img,
                                       urlargd={})
            if text != '':
                out += '''
                        <tr><td class="article">
                           <h%(header_tag_size)s class="%(css_classes)s articleTitle" style="clear:both;">
                               <a title="link to the article" href="%(article_link)s">%(title)s</a>
                           </h%(header_tag_size)s>
                           <div class="articleBody">
                               %(img)s
                               %(text)s
                               %(more_link)s
                           </div>
                       </td></tr>
                    ''' % {
                    'article_link': article_link,
                    'title': title,
                    'img': img,
                    'text': text,
                    'more_link': more_link,
                    'css_classes': ' '.join(css_classes),
                    'header_tag_size': header_tag_size
                }
            else:
                out += '''
                       <tr><td class="article">
                           <h%(header_tag_size)s class="%(css_classes)s articleTitle" style="clear:both;">
                               <a title="link to the article" href="%(article_link)s">%(title)s</a>&nbsp;&nbsp;
                               %(more_link)s
                           </h%(header_tag_size)s>
                           %(img)s
                       </td></tr>
                       ''' % {
                    'article_link': article_link,
                    'title': title,
                    'more_link': more_link,
                    'img': img,
                    'css_classes': ' '.join(css_classes),
                    'header_tag_size': header_tag_size
                }
    out += '</table>'
    if verbose == 0 and not CFG_ACCESS_CONTROL_LEVEL_SITE == 2:
        cache_index_page(out, journal_name, category_name, this_issue_number,
                         ln)

    return out
def format_element(bfo, new_articles_first='yes',
           subject_to_css_class_kb="WebJournalSubject2CSSClass",
           display_all_category_articles='no'):
    """
    Creates a navigation for articles in the same issue and category.

    @param new_articles_first: if 'yes', display new articles before other articles
    @param subject_to_css_class_kb: knowledge base that maps 595__a to a CSS class
    @param display_all_category_articles: if yes, display all articles, whatever category is selected
    """
    # get variables
    args = parse_url_string(bfo.user_info['uri'])
    this_recid = bfo.control_field('001')
    this_issue_number = args["issue"]
    category_name = args["category"]
    journal_name = args["journal_name"]
    ln = bfo.lang
    _ = gettext_set_language(ln)

    this_title = ""
    if ln == "fr":
        if bfo.fields('246_1a'):
            this_title = bfo.fields('246_1a')[0]
        elif bfo.fields('245__a'):
            this_title = bfo.fields('245__a')[0]
    else:
        if bfo.fields('245__a'):
            this_title = bfo.fields('245__a')[0]
        elif bfo.fields('246_1a'):
            this_title = bfo.fields('246_1a')[0]

    journal_categories = [category_name]
    if display_all_category_articles.lower() == 'yes':
        # Let's retrieve all categories. Ok, we are not supposed to do
        # that with that element, but if journal editor wants...
        journal_categories = get_journal_categories(journal_name,
                                                    this_issue_number)

    menu_out = ''

    for category in journal_categories:
        ordered_articles = get_journal_articles(journal_name,
                                                this_issue_number,
                                                category,
                                                newest_first=new_articles_first.lower() == 'yes')

        new_articles_only = False
        if ordered_articles.keys() and max(ordered_articles.keys()) < 0:
            # If there are only new articles, don't bother marking them as
            # new
            new_articles_only = True

        menu_out += '<div class="subNavigationMenu">'
        order_numbers = ordered_articles.keys()
        order_numbers.sort()
        for order_number in order_numbers:
            for article_id in ordered_articles[order_number]:
                # A record is considered as new if its position is
                # negative and there are some non-new articles
                article_is_new = (order_number < 0 and not new_articles_only)

                if str(article_id) == this_recid:
                    # Mark as active

                    # Get CSS class (if relevant)
                    notes = bfo.fields('595__a')
                    css_classes = [bfo.kb(subject_to_css_class_kb, note, None) \
                                   for note in notes]
                    css_classes = [css_class for css_class in css_classes \
                                   if css_class is not None]

                    if article_is_new:
                        css_classes.append('new')

                    separator = bfo.field('594__a')
                    if separator == "YES":
                        menu_out += '''<hr/>'''

                    menu_out += '''<div class="active">
            <div class="subNavigationMenuItem %s">%s</div></div>''' % \
                    (' '.join(css_classes),
                     this_title)

                else:
                    temp_rec = BibFormatObject(article_id)
                    title = ''
                    if ln == "fr":
                        title = temp_rec.field('246_1a')
                        if title == '':
                            title = temp_rec.field('245__a')
                    else:
                        title = temp_rec.field('245__a')
                        if title == '':
                            title = temp_rec.field('246_1a')

                    # Get CSS class (if relevant)
                    notes = temp_rec.fields('595__a')
                    css_classes = [temp_rec.kb(subject_to_css_class_kb, note, None) \
                                   for note in notes]
                    css_classes = [css_class for css_class in css_classes \
                                   if css_class is not None]

                    if article_is_new:
                        css_classes.append('new')

                    separator = temp_rec.field('594__a')
                    if separator == "YES":
                        menu_out += '''<hr/>'''

                    menu_out += '''<div class="subNavigationMenuItem %s">
                    <a href="%s">%s</a></div>
                    ''' % (' '.join(css_classes),
                           make_journal_url(bfo.user_info['uri'],
                                            {'recid': article_id,
                                             'ln': bfo.lang,
                                             'category': category}),
                           title)

        menu_out += '</div>'

    return menu_out
def format_element(bfo, new_articles_first='yes',
           subject_to_css_class_kb="WebJournalSubject2CSSClass",
           display_all_category_articles='no', display_category_title='no'):
    """
    List all articles one after the other, on the same page.

    Similar to bfe_webjournal_articles_overview, but displays full articles.

    Note that you cannot use both bfe_webjournal_articles_overview and
    bfe_webjournal_articles: you have to choose one of them, as they
    use the same cache location (It would also not make sense to use
    both...).

    @param new_articles_first: if 'yes', display new articles before other articles
    @param subject_to_css_class_kb: knowledge base that maps 595__a to a CSS class
    @param display_all_category_articles: if yes, display all articles, whatever category is selected
    @param display_category_title: if yes, display category title (useful if display_all_category_articles is enabled)

    @see: bfe_webjournal_articles_overview.py
    """
    args = parse_url_string(bfo.user_info['uri'])
    journal_name = args["journal_name"]
    this_issue_number = args["issue"]
    category_name = args["category"]
    verbose = args["verbose"]
    ln = bfo.lang
    _ = gettext_set_language(ln)

    # Try to get the page from cache. Only if issue is older or equal
    # to latest release.
    latest_released_issue = get_current_issue(ln, journal_name)
    if verbose == 0 and not issue_is_later_than(this_issue_number,
                                                latest_released_issue):
        cached_html = get_index_page_from_cache(journal_name, category_name,
                                                this_issue_number, ln)
        if cached_html:
            return cached_html

    # Shall we display current category, or all?
    categories = [category_name]
    if display_all_category_articles.lower() == 'yes':
        categories = get_journal_categories(journal_name,
                                            this_issue_number)

    out = ''
    for category_name in categories:
        if display_category_title.lower() == 'yes':
            out += '<h2>' + _(category_name) + '</h2>'

        out += '<table border="0" cellpadding="0" cellspacing="0">'
        # Get the id list
        ordered_articles = get_journal_articles(journal_name,
                                                this_issue_number,
                                                category_name,
                                                newest_first=new_articles_first.lower() == 'yes')
        new_articles_only = False
        if ordered_articles.keys() and max(ordered_articles.keys()) < 0:
            # If there are only new articles, don't bother marking them as
            # new
            new_articles_only = True

        order_numbers = ordered_articles.keys()
        order_numbers.sort()

        for order_number in order_numbers:
            for article_id in ordered_articles[order_number]:
                # A record is considered as new if its position is
                # negative and there are some non-new articles
                article_is_new = (order_number < 0 and not new_articles_only)

                temp_rec = BibFormatObject(article_id)
                title = ''
                if ln == "fr":
                    title = temp_rec.field('246_1a')
                    if title == '':
                        title = temp_rec.field('245__a')
                else:
                    title = temp_rec.field('245__a')
                    if title == '':
                        title = temp_rec.field('246_1a')

                # Get CSS class (if relevant)
                notes = temp_rec.fields('595__a')
                css_classes = [temp_rec.kb(subject_to_css_class_kb, note, None) \
                               for note in notes]
                css_classes = [css_class for css_class in css_classes \
                               if css_class is not None]

                if article_is_new:
                    css_classes.append('new')

                # Finally create the output. Two different outputs
                # depending on if we have text to display or not
                text = []
                if ln == "fr":
                    text = temp_rec.fields('590__b')
                    if not text or \
                           (len(text) == 1 and \
                            (text[0].strip() in ['', '<br />', '<!--HTML--><br />'])):
                        text = temp_rec.fields('520__b')
                else:
                    text = temp_rec.fields('520__b')
                    if not text or \
                           (len(text) == 1 and \
                            (text[0].strip() in ['', '<br />', '<!--HTML--><br />'])):
                        text = temp_rec.fields('590__b')
                text = '<br/>'.join(text)


                out += '''
                            <tr><td class="article">
                               <h%(header_tag_size)s class="%(css_classes)s articleTitle" style="clear:both;">
                                   %(title)s
                               </h%(header_tag_size)s>
                               <div class="articleBody">
                                   <div class="articleText">
                                      %(text)s
                                   </div>
                               </div>
                           </td></tr>
                        ''' % {'title': title,
                               'text': text,
                               'header_tag_size': (display_category_title.lower() == 'yes') and '3' or '2',
                               'css_classes': ' '.join(css_classes)}
        out += '</table>'

    if verbose == 0 and not CFG_ACCESS_CONTROL_LEVEL_SITE == 2 :
        cache_index_page(out, journal_name, category_name,
                         this_issue_number, ln)

    return out
Beispiel #22
0
def test():
    """
    Test the function
    """
    from invenio.modules.formatter.engine import BibFormatObject

    xml1 = '''
<record>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo1 = BibFormatObject(0, xml_record=xml1)
    assert (format_element(bfo1) == '&copy; CERN')

    xml2 = '''
<record>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="f">ATLAS Experiment © CERN</subfield>
    </datafield>
</record>'''

    bfo2 = BibFormatObject(0, xml_record=xml2)
    assert (format_element(bfo2) == 'ATLAS Experiment &copy; CERN')

    xml3 = '''
<record>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">BBC</subfield>
    </datafield>
</record>'''

    bfo3 = BibFormatObject(0, xml_record=xml3)
    assert (format_element(bfo3) == '&copy; BBC')

    xml4 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="u">http://cern.ch</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo4 = BibFormatObject(0, xml_record=xml4)
    assert (format_element(bfo4) == '<a href="http://cern.ch">&copy; CERN</a>')

    xml5 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">BBC</subfield>
    </datafield>
</record>'''

    bfo5 = BibFormatObject(0, xml_record=xml5)
    assert (
        format_element(bfo5) == '<a href="http://bbc.co.uk">&copy; BBC</a>')

    xml6 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo6 = BibFormatObject(0, xml_record=xml6)
    assert (format_element(bfo6) ==
            '&copy; CERN (License: <a href="http://bbc.co.uk">BBC</a>)')

    xml7 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">1</subfield>
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo7 = BibFormatObject(0, xml_record=xml7)
    assert (format_element(bfo7) ==
            '&copy; CERN, <a href="http://bbc.co.uk">BBC</a>')

    xml8 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">1</subfield>
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo8 = BibFormatObject(0, xml_record=xml8)
    assert (format_element(bfo8) ==
            '&copy; CERN (License: <a href="http://bbc.co.uk">BBC</a>)')

    xml9 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="8">2</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">2</subfield>
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo9 = BibFormatObject(0, xml_record=xml9)
    assert (format_element(bfo9) ==
            '&copy; CERN, <a href="http://bbc.co.uk">BBC</a>')

    xml10 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="8">2</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">1</subfield>
        <subfield code="d">BBC</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">2</subfield>
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo10 = BibFormatObject(0, xml_record=xml10)
    assert (format_element(bfo10) ==
            '<a href="http://bbc.co.uk">&copy; BBC</a>, &copy; CERN')

    xml11 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC License 1</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="8">2</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">1</subfield>
        <subfield code="d">BBC</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">2</subfield>
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo11 = BibFormatObject(0, xml_record=xml11)
    assert (
        format_element(bfo11) ==
        '&copy; CERN, &copy; BBC (<a href="http://bbc.co.uk">BBC License 1</a>)'
    )

    xml12 = '''
<record>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo12 = BibFormatObject(0, xml_record=xml12)
    assert (format_element(
        bfo12,
        auto_link_to_CERN_license='yes') == '<a href="%s">&copy; CERN</a>' %
            CFG_CERN_LICENSE_URL)

    xml13 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
    </datafield>
    <datafield tag="269" ind1=" " ind2=" ">
        <subfield code="b">CERN</subfield>
        <subfield code="c">2010</subfield>
    </datafield>
</record>'''

    bfo13 = BibFormatObject(0, xml_record=xml13)
    assert (format_element(
        bfo13,
        auto_link_to_CERN_license='yes') == '<a href="%s">&copy; CERN</a>' %
            CFG_CERN_LICENSE_URL)

    #     xml14 = '''
    # <record>
    #     <datafield tag="269" ind1=" " ind2=" ">
    #         <subfield code="b">CERN</subfield>
    #         <subfield code="c">2010</subfield>
    #     </datafield>
    # </record>'''

    #     bfo14 = BibFormatObject(0, xml_record=xml14)
    #     assert(format_element(bfo14, auto_link_to_CERN_license='yes')  == 'CERN')

    xml15 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC License 1</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="8">2</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">1</subfield>
        <subfield code="d">BBC</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">2</subfield>
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo15 = BibFormatObject(0, xml_record=xml15)
    assert (format_element(
        bfo15, show_licenses='no',
        instances_separator=" &amp; ") == '&copy; BBC &amp; &copy; CERN')

    xml16 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC License 1</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="8">2</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">1</subfield>
        <subfield code="d">BBC</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">2</subfield>
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo16 = BibFormatObject(0, xml_record=xml16)
    assert (format_element(
        bfo16,
        link_to_licenses='no') == '&copy; BBC (BBC License 1), &copy; CERN')

    xml17 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC License 1</subfield>
        <subfield code="u">http://bbc.co.uk/license1</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC License 2</subfield>
        <subfield code="u">http://bbc.co.uk/license2</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="8">2</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">1</subfield>
        <subfield code="d">BBC</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="8">2</subfield>
        <subfield code="d">CERN</subfield>
    </datafield>
</record>'''

    bfo17 = BibFormatObject(0, xml_record=xml17)
    assert (
        format_element(bfo17) ==
        '&copy; CERN, &copy; BBC (<a href="http://bbc.co.uk/license1">BBC License 1</a>, <a href="http://bbc.co.uk/license2">BBC License 2</a>)'
    )

    xml18 = '''
<record>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="g">1984</subfield>
    </datafield>
</record>'''

    bfo18 = BibFormatObject(0, xml_record=xml18)
    assert (format_element(bfo18) == '&copy; 1984 CERN')

    xml19 = '''
<record>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="g">1984</subfield>
        <subfield code="f">ATLAS Experiment © CERN</subfield>
    </datafield>
</record>'''

    bfo19 = BibFormatObject(0, xml_record=xml19)
    assert (format_element(bfo19) == 'ATLAS Experiment &copy; CERN')

    xml20 = '''
<record>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">BBC</subfield>
        <subfield code="g">1984</subfield>
    </datafield>
</record>'''

    bfo20 = BibFormatObject(0, xml_record=xml20)
    assert (format_element(bfo20) == '&copy; 1984 BBC')

    xml21 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="u">http://cern.ch</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="g">1984</subfield>
    </datafield>
</record>'''

    bfo21 = BibFormatObject(0, xml_record=xml21)
    assert (format_element(bfo21) ==
            '<a href="http://cern.ch">&copy; 1984 CERN</a>')

    xml22 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">BBC</subfield>
        <subfield code="u">http://bbc.co.uk</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">BBC</subfield>
        <subfield code="g">1984</subfield>
    </datafield>
</record>'''

    bfo22 = BibFormatObject(0, xml_record=xml22)
    assert (format_element(bfo22) ==
            '<a href="http://bbc.co.uk">&copy; 1984 BBC</a>')

    xml23 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CC-BY-3.0</subfield>
        <subfield code="u">http://creativecommons.org/licenses/by/3.0/</subfield>
        <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CC-BY-3.0</subfield>
        <subfield code="u">http://creativecommons.org/licenses/by/3.0/</subfield>
        <subfield code="3">Publication</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="g">2011</subfield>
        <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="g">2012</subfield>
       <subfield code="3">Publication</subfield>
    </datafield>
</record>'''

    bfo23 = BibFormatObject(0, xml_record=xml23)
    assert (
        format_element(bfo23) ==
        'Publication: &copy; 2012 CERN (License: <a href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a>), Preprint: &copy; 2011 CERN (License: <a href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a>)'
    )

    xml24 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CC-BY-3.0</subfield>
        <subfield code="u">http://creativecommons.org/licenses/by/3.0/</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CC-BY-3.0</subfield>
        <subfield code="u">http://creativecommons.org/licenses/by/3.0/</subfield>
        <subfield code="3">Publication</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="g">2011</subfield>
        <subfield code="8">1</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="g">2012</subfield>
       <subfield code="3">Publication</subfield>
    </datafield>
</record>'''

    bfo24 = BibFormatObject(0, xml_record=xml24)
    assert (
        format_element(bfo24) ==
        'Publication: &copy; 2012 CERN (License: <a href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a>), &copy; 2011 CERN (License: <a href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a>)'
    )

    xml25 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CC-BY-3.0</subfield>
        <subfield code="u">http://creativecommons.org/licenses/by/3.0/</subfield>
        <subfield code="3">Publication</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="g">2011</subfield>
        <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">FOO</subfield>
        <subfield code="g">2012</subfield>
       <subfield code="3">Publication</subfield>
    </datafield>
</record>'''

    bfo25 = BibFormatObject(0, xml_record=xml25)
    assert (
        format_element(bfo25, auto_link_to_CERN_license='yes') ==
        'Publication: &copy; 2012 FOO (License: <a href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a>), Preprint: <a href="http://copyright.cern.ch/">&copy; 2011 CERN</a>'
    )

    xml26 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CC-BY-3.0</subfield>
        <subfield code="3">Publication</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
        <subfield code="a">CERN</subfield>
        <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">CERN</subfield>
        <subfield code="g">2011</subfield>
        <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
        <subfield code="d">FOO</subfield>
        <subfield code="g">2012</subfield>
       <subfield code="3">Publication</subfield>
    </datafield>
</record>'''

    bfo26 = BibFormatObject(0, xml_record=xml26)
    assert (
        format_element(bfo26, remove_link_to_CERN_license="no") ==
        'Publication: &copy; 2012 FOO (License: <a href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a>), Preprint: <a href="http://copyright.cern.ch/">&copy; 2011 CERN</a>'
    )

    xml27 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
       <subfield code="f">SCOAP3</subfield>
       <subfield code="a">CC-BY-3.0</subfield>
       <subfield code="3">Publication</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
       <subfield code="a">CERN</subfield>
       <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
       <subfield code="d">CERN</subfield>
       <subfield code="g">2011</subfield>
       <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
       <subfield code="d">ESA</subfield>
       <subfield code="g">2014</subfield>
      <subfield code="3">Publication</subfield>
    </datafield>
</record>'''

    bfo27 = BibFormatObject(0, xml_record=xml27)
    assert (
        format_element(bfo27, remove_link_to_CERN_license="yes") ==
        'Preprint: &copy; 2011 CERN, Publication: &copy; 2014 ESA (License: <a href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a>), sponsored by <a href="http://scoap3.org">SCOAP&#179;</a>'
    )

    xml28 = '''
<record>
    <datafield tag="540" ind1=" " ind2=" ">
       <subfield code="f">SCOAP3</subfield>
       <subfield code="a">CC-BY-3.0</subfield>
       <subfield code="3">Publication</subfield>
    </datafield>
    <datafield tag="540" ind1=" " ind2=" ">
       <subfield code="a">CERN</subfield>
       <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
       <subfield code="d">CERN</subfield>
       <subfield code="g">2011</subfield>
       <subfield code="3">Preprint</subfield>
    </datafield>
    <datafield tag="542" ind1=" " ind2=" ">
       <subfield code="d">ESA</subfield>
       <subfield code="g">2014</subfield>
      <subfield code="3">Publication</subfield>
    </datafield>
</record>'''

    bfo28 = BibFormatObject(0, xml_record=xml28)
    assert (
        format_element(bfo28,
                       remove_link_to_CERN_license="yes",
                       show_sponsor="no") ==
        'Preprint: &copy; 2011 CERN, Publication: &copy; 2014 ESA (License: <a href="http://creativecommons.org/licenses/by/3.0/">CC-BY-3.0</a>)'
    )

    print("All tests run ok")
def format_element(bfo,
                   new_articles_first='yes',
                   subject_to_css_class_kb="WebJournalSubject2CSSClass",
                   display_all_category_articles='no'):
    """
    Creates a navigation for articles in the same issue and category.

    @param new_articles_first: if 'yes', display new articles before other articles
    @param subject_to_css_class_kb: knowledge base that maps 595__a to a CSS class
    @param display_all_category_articles: if yes, display all articles, whatever category is selected
    """
    # get variables
    args = parse_url_string(bfo.user_info['uri'])
    this_recid = bfo.control_field('001')
    this_issue_number = args["issue"]
    category_name = args["category"]
    journal_name = args["journal_name"]
    ln = bfo.lang
    _ = gettext_set_language(ln)

    this_title = ""
    if ln == "fr":
        if bfo.fields('246_1a'):
            this_title = bfo.fields('246_1a')[0]
        elif bfo.fields('245__a'):
            this_title = bfo.fields('245__a')[0]
    else:
        if bfo.fields('245__a'):
            this_title = bfo.fields('245__a')[0]
        elif bfo.fields('246_1a'):
            this_title = bfo.fields('246_1a')[0]

    journal_categories = [category_name]
    if display_all_category_articles.lower() == 'yes':
        # Let's retrieve all categories. Ok, we are not supposed to do
        # that with that element, but if journal editor wants...
        journal_categories = get_journal_categories(journal_name,
                                                    this_issue_number)

    menu_out = ''

    for category in journal_categories:
        ordered_articles = get_journal_articles(
            journal_name,
            this_issue_number,
            category,
            newest_first=new_articles_first.lower() == 'yes')

        new_articles_only = False
        if ordered_articles.keys() and max(ordered_articles.keys()) < 0:
            # If there are only new articles, don't bother marking them as
            # new
            new_articles_only = True

        menu_out += '<div class="subNavigationMenu">'
        order_numbers = ordered_articles.keys()
        order_numbers.sort()
        for order_number in order_numbers:
            for article_id in ordered_articles[order_number]:
                # A record is considered as new if its position is
                # negative and there are some non-new articles
                article_is_new = (order_number < 0 and not new_articles_only)

                if str(article_id) == this_recid:
                    # Mark as active

                    # Get CSS class (if relevant)
                    notes = bfo.fields('595__a')
                    css_classes = [bfo.kb(subject_to_css_class_kb, note, None) \
                                   for note in notes]
                    css_classes = [css_class for css_class in css_classes \
                                   if css_class is not None]

                    if article_is_new:
                        css_classes.append('new')

                    separator = bfo.field('594__a')
                    if separator == "YES":
                        menu_out += '''<hr/>'''

                    menu_out += '''<div class="active">
            <div class="subNavigationMenuItem %s">%s</div></div>''' % \
                    (' '.join(css_classes),
                     this_title)

                else:
                    temp_rec = BibFormatObject(article_id)
                    title = ''
                    if ln == "fr":
                        title = temp_rec.field('246_1a')
                        if title == '':
                            title = temp_rec.field('245__a')
                    else:
                        title = temp_rec.field('245__a')
                        if title == '':
                            title = temp_rec.field('246_1a')

                    # Get CSS class (if relevant)
                    notes = temp_rec.fields('595__a')
                    css_classes = [temp_rec.kb(subject_to_css_class_kb, note, None) \
                                   for note in notes]
                    css_classes = [css_class for css_class in css_classes \
                                   if css_class is not None]

                    if article_is_new:
                        css_classes.append('new')

                    separator = temp_rec.field('594__a')
                    if separator == "YES":
                        menu_out += '''<hr/>'''

                    menu_out += '''<div class="subNavigationMenuItem %s">
                    <a href="%s">%s</a></div>
                    ''' % (' '.join(css_classes),
                           make_journal_url(
                               bfo.user_info['uri'], {
                                   'recid': article_id,
                                   'ln': bfo.lang,
                                   'category': category
                               }), title)

        menu_out += '</div>'

    return menu_out
def format_element(bfo, latest_issue_only='yes', newest_articles_only='yes',
           link_category_headers='yes', display_categories='', hide_when_only_new_records="no"):
    """
    Display the index to the newest articles (of the latest issue, or of the displayed issue)

    @param latest_issue_only: if 'yes', always display articles of the latest issue, even if viewing a past issue
    @param newest_articles_only: only display new articles, not those that also appeared in previous issues
    @param link_category_headers: if yes, category headers link to index page of that category
    @param display_categories: comma-separated list of categories to display. If none, display all
    @param hide_when_only_new_records: if 'yes' display new articles only if old articles exist in this issue
    """
    args = parse_url_string(bfo.user_info['uri'])
    journal_name = args["journal_name"]
    ln = bfo.lang
    _ = gettext_set_language(ln)

    if latest_issue_only.lower() == 'yes':
        issue_number = get_current_issue(bfo.lang, journal_name)
    else:
        issue_number = args["issue"]

    # Try to get HTML from cache
    if args['verbose'] == 0:
        cached_html = _get_whatsNew_from_cache(journal_name, issue_number, ln)
        if cached_html:
            return cached_html

    # No cache? Build from scratch
    # 1. Get the articles
    journal_categories = get_journal_categories(journal_name,
                                                issue_number)
    if display_categories:
        display_categories = display_categories.lower().split(',')
        journal_categories = [category for category in journal_categories \
                              if category.lower() in display_categories]
    whats_new_articles = {}
    for category in journal_categories:
        whats_new_articles[category] = get_journal_articles(journal_name,
                                                            issue_number,
                                                            category,
                                                            newest_only=newest_articles_only.lower() == 'yes')

    # Do we want to display new articles only if they have been added
    # to an issue that contains non-new records?
    if hide_when_only_new_records.lower() == "yes":
        # First gather all articles in this issue
        all_whats_new_articles = {}
        for category in journal_categories:
            all_whats_new_articles[category] = get_journal_articles(journal_name,
                                                                    issue_number,
                                                                    category,
                                                                    newest_first=True,
                                                                    newest_only=False)
        # Then check if we have some articles at position > -1
        has_old_articles = False
        for articles in all_whats_new_articles.values():
            if len([order for order in articles.keys() if order > -1]) > 0:
                has_old_articles = True
                break
        if not has_old_articles:
            # We don't have old articles? Thend don't consider any
            for category in journal_categories:
                whats_new_articles[category] = {}

    # 2. Build the HTML
    html_out = _get_breaking_news(ln, journal_name)
    for category in journal_categories:
        articles_in_category = whats_new_articles[category]
        html_articles_in_category = ""
        # Generate the list of articles in this category
        order_numbers = articles_in_category.keys()
        order_numbers.sort()
        for order in order_numbers:
            articles = articles_in_category[order]
            for recid in articles:
                link = make_journal_url(bfo.user_info['uri'], {'journal_name': journal_name,
                                                               'issue_number': issue_number.split('/')[0],
                                                               'issue_year': issue_number.split('/')[1],
                                                               'category': category,
                                                               'recid': recid,
                                                               'ln': bfo.lang})
                temp_rec = BibFormatObject(recid)
                if ln == 'fr':
                    try:
                        title = temp_rec.fields('246_1a')[0]
                    except:
                        try:
                            title = temp_rec.field('245__a')
                        except:
                            continue
                else:
                    try:
                        title = temp_rec.field('245__a')
                    except:
                        continue
                try:
                    html_articles_in_category += '<li><a href="%s">%s</a></li>' % \
                                                 (link, title)
                except:
                    pass

        if html_articles_in_category:
            # Good, we found some new articles for this category.
            # Then insert the genereated results into a larger list
            # with category as "parent".
            html_out += '<li>'
            if link_category_headers.lower() == 'yes':
                html_out += '<a href="'
                html_out += make_journal_url(bfo.user_info['uri'],
                                             {'journal_name': journal_name,
                                              'issue_number': issue_number.split('/')[0],
                                              'issue_year': issue_number.split('/')[1],
                                              'category': category,
                                              'recid': '',
                                              'ln': bfo.lang})
                html_out += '" class="whatsNewCategory">%s</a>' % _(category)
            else:
                html_out += '<span class="whatsNewCategory">%s</span>' % _(category)

            html_out += '<ul class="whatsNewItem">'
            html_out += html_articles_in_category
            html_out += '</ul></li>'

    if not html_out:
        html_out = '<i>' + _('There are no new articles for the moment') + '</i>'
    else:
        html_out = '<ul class="whatsNew">' + html_out + '</ul>'

    if args['verbose'] == 0:
        cache_whatsNew(html_out, journal_name, issue_number, ln)

    return html_out
Beispiel #25
0
def perform_request_article(req, journal_name, issue_number, ln,
                            category, recid, editor=False, verbose=0):
    """
    Central logic function for article pages.
    Loads the format template for article display and displays the requested
    article using BibFormat.
    'Editor' mode generates edit links on the article view page and disables
    caching.
    """
    current_issue = get_current_issue(ln, journal_name)
    if not get_release_datetime(issue_number, journal_name):
        # Unreleased issue. Display latest released issue?
        unreleased_issues_mode = get_unreleased_issue_hiding_mode(journal_name)
        if not editor and \
               (unreleased_issues_mode == 'all' or \
                (unreleased_issues_mode == 'future' and \
                 issue_is_later_than(issue_number, current_issue))):
            redirect_to_url(req, "%s/journal/%s/%s/%s?ln=%s" % \
                            (CFG_SITE_URL,
                             journal_name,
                             current_issue.split('/')[1],
                             current_issue.split('/')[0],
                             ln))

    try:
        index_page_template = get_journal_template('detailed',
                                                   journal_name,
                                                   ln)
    except InvenioWebJournalTemplateNotFoundError as e:
        register_exception(req=req)
        return e.user_box(req)

    user_info = collect_user_info(req)
    bfo = BibFormatObject(recid, ln=ln, user_info=user_info)
    bfo.req = req

    # if it is cached, return it
    cached_html = get_article_page_from_cache(journal_name, category,
                                              recid, issue_number, ln,
                                              bfo)

    if cached_html and not editor:
        return cached_html

    # Check that this recid is indeed an article
    is_article = False
    articles = get_journal_articles(journal_name, issue_number, category)
    for order, recids in iteritems(articles):
        if recid in recids:
            is_article = True
            break

    if not is_article:
        redirect_to_url(req, "%s/journal/%s/%s/%s?ln=%s" % \
                        (CFG_SITE_URL,
                         journal_name,
                         issue_number.split('/')[1],
                         issue_number.split('/')[0],
                         ln))


    # create a record and get HTML back from bibformat
    verbosity = 0
    if editor:
        # Increase verbosity only for editors/admins
        verbosity = verbose
    html_out = format_with_format_template(index_page_template,
                                           bfo,
                                           verbose=verbosity)
    # cache if not in editor mode, and if database is not down
    if not editor and not CFG_ACCESS_CONTROL_LEVEL_SITE == 2:
        cache_article_page(html_out, journal_name, category,
                           recid, issue_number, ln)

    return html_out
def format_element(bfo, number_of_featured_articles="1",
           number_of_articles_with_image="3", new_articles_first='yes',
           image_px_width="300", small_image_px_width="200",
           subject_to_css_class_kb="WebJournalSubject2CSSClass",
           link_image_to_article='yes', image_alignment='left'):
    """
    Creates an overview of all the articles of a certain category in one
    specific issue.

    Note the following:
    <ul>
    <li>The element consider only the latest issue: when viewing
    archives of your journal, readers will see the newest articles of
    the latest issue, not the ones of the issue they are looking
    at</li>

    <li>This is not an index of the articles of the latest issue: it
    display only <b>new</b> articles, that is articles that have never
    appeared in a previous issue</li>

    <li>This element produces a table-based layout, in order to have a
    more or less readable HTML alert when sent some Email clients
    (Outlook 2007)</li>

    <li>When producing the HTML output of images, this element tries to
    insert the width and height attributes to the img tag: this is
    necessary in order to produce nice HTML alerts. This dimension
    therefore overrides any dimension defined in the CSS. The Python
    Image Library (PIL) should be installed for this element to
    recognize the size of images.</li>
    </ul>

    @param number_of_featured_articles: the max number of records with emphasized title
    @param number_of_articles_with_image: the max number of records for which their image is displayed
    @param new_articles_first: if 'yes', display new articles before other articles
    @param image_px_width: (integer) width of first image featured on this page
    @param small_image_px_width: (integer) width of small images featured on this page
    @param subject_to_css_class_kb: knowledge base that maps 595__a to a CSS class
    @param link_image_to_article: if 'yes', link image (if any) to article
    @param image_alignment: 'left', 'center' or 'right'. To help rendering in Outlook.
    """
    args = parse_url_string(bfo.user_info['uri'])
    journal_name = args["journal_name"]
    this_issue_number = args["issue"]
    category_name = args["category"]
    verbose = args["verbose"]
    ln = bfo.lang
    _ = gettext_set_language(ln)

    if image_px_width.isdigit():
        image_px_width = int(image_px_width)
    else:
        image_px_width = None
    if small_image_px_width.isdigit():
        small_image_px_width = int(small_image_px_width)
    else:
        small_image_px_width = None

    # We want to put emphasis on the n first articles (which are not
    # new)
    if number_of_featured_articles.isdigit():
        number_of_featured_articles = int(number_of_featured_articles)
    else:
        number_of_featured_articles = 0

    # Only n first articles will display images
    if number_of_articles_with_image.isdigit():
        number_of_articles_with_image = int(number_of_articles_with_image)
    else:
        number_of_articles_with_image = 0

    # Help image alignement without CSS, to have better rendering in Outlook
    img_align = ''
    if image_alignment:
        img_align = 'align="%s"' % image_alignment

    # Try to get the page from cache. Only if issue is older or equal
    # to latest release.
    latest_released_issue = get_current_issue(ln, journal_name)
    if verbose == 0 and not issue_is_later_than(this_issue_number,
                                                latest_released_issue):
        cached_html = get_index_page_from_cache(journal_name, category_name,
                                                this_issue_number, ln)
        if cached_html:
            return cached_html

    out = '<table border="0" cellpadding="0" cellspacing="0">'
    # Get the id list
    ordered_articles = get_journal_articles(journal_name,
                                            this_issue_number,
                                            category_name,
                                            newest_first=new_articles_first.lower() == 'yes')
    new_articles_only = False
    if ordered_articles.keys() and max(ordered_articles.keys()) < 0:
        # If there are only new articles, don't bother marking them as
        # new
        new_articles_only = True

    order_numbers = ordered_articles.keys()
    order_numbers.sort()
    img_css_class = "featuredImageScale"

    for order_number in order_numbers:
        for article_id in ordered_articles[order_number]:
            # A record is considered as new if its position is
            # negative and there are some non-new articles
            article_is_new = (order_number < 0 and not new_articles_only)

            temp_rec = BibFormatObject(article_id)
            title = ''
            if ln == "fr":
                title = temp_rec.field('246_1a')
                if title == '':
                    title = temp_rec.field('245__a')
            else:
                title = temp_rec.field('245__a')
                if title == '':
                    title = temp_rec.field('246_1a')

            # Get CSS class (if relevant)
            notes = temp_rec.fields('595__a')
            css_classes = [temp_rec.kb(subject_to_css_class_kb, note, None) \
                           for note in notes]
            css_classes = [css_class for css_class in css_classes \
                           if css_class is not None]

            if article_is_new:
                css_classes.append('new')

            # Maybe we want to force image to appear?
            display_image_on_index = False
            if 'display_image_on_index' in notes:
                display_image_on_index = True

            # Build generic link to this article
            article_link = make_journal_url(bfo.user_info['uri'], {'recid':str(article_id),
                                                                   'ln': bfo.lang})

            # Build the "more" link
            more_link = '''<a class="readMore" title="link to the article" href="%s"> &gt;&gt; </a>
                        ''' % (article_link)

            # If we should display an image along with the text,
            # prepare it here
            img = ''
            if (number_of_articles_with_image > 0 and \
                   not article_is_new) or display_image_on_index:
                img = _get_feature_image(temp_rec, ln)
                if img != "":
                    # Now we will try to identify image size in order
                    # to resize it in the HTML for a nicer rendering
                    # of the HTML alert in email clients (Outlook wants
                    # both height and width)
                    img_width = None
                    img_height = None
                    small_img_width = None
                    small_img_height = None
                    width_and_height = ''
                    if PIL_imported:
                        try:
                            local_img = os.path.join(CFG_TMPDIR,
                                                     'webjournal_' + \
                                                     ''.join([char for char in img \
                                                              if char.isalnum()]))
                            if len(local_img) > 255:
                                # Shorten to 255 chars
                                local_img = local_img[0:100] + '_' + local_img[156:]
                            if not os.path.exists(local_img):
                                # Too bad, must download entire image for PIL
                                content_type = get_content_type(img)
                                if 'image' in content_type:
                                    (local_img, headers) = urllib.urlretrieve(img, local_img)
                                    img_file = Image.open(local_img) # IOError if not readable image
                                else:
                                    raise IOError('Not an image')
                            else:
                                img_file = Image.open(local_img) # IOError if not readable image
                        except IOError as e:
                            pass
                        else:
                            orig_img_width = img_file.size[0]
                            orig_img_height = img_file.size[1]
                            # Then scale according to user-defined width
                            ## First image
                            ratio = float(orig_img_width) / image_px_width
                            img_width = image_px_width
                            img_height = int(orig_img_height / ratio)
                            ## Other smaller images
                            ratio = float(orig_img_width) / small_image_px_width
                            small_img_width = small_image_px_width
                            small_img_height = int(orig_img_height / ratio)

                    # Note that we cannot reuse the nice phl, ph and
                    # phr classes to put a frame around the image:
                    # this is not supported in Outlook 2007 when HTML
                    # alert is sent.
                    if not img_css_class == "featuredImageScale":
                        # Not first image: display smaller
                        img_width = small_img_width
                        img_height = small_img_height

                    if img_width and img_height:
                        width_and_height = 'width="%i" height="%i"' % \
                                           (img_width, img_height)
                    img = '<img alt="" class="%s" src="%s" %s %s/>' % \
                          (img_css_class, img, img_align, width_and_height)
                    number_of_articles_with_image -= 1

                    # Next images will be displayed smaller
                    img_css_class = "featuredImageScaleSmall"

            # Determine size of the title
            header_tag_size = '3'
            if number_of_featured_articles > 0 and \
                   not article_is_new:
                # n first articles are especially featured
                header_tag_size = '2'
                number_of_featured_articles -= 1

            # Finally create the output. Two different outputs
            # depending on if we have text to display or not
            text = ''
            if not article_is_new:
                text = _get_feature_text(temp_rec, ln)
            # Link image to article if wanted
            if link_image_to_article.lower() == 'yes':
                img = create_html_link(urlbase=article_link,
                                       link_label=img,
                                       urlargd={})
            if text != '':
                out += '''
                        <tr><td class="article">
                           <h%(header_tag_size)s class="%(css_classes)s articleTitle" style="clear:both;">
                               <a title="link to the article" href="%(article_link)s">%(title)s</a>
                           </h%(header_tag_size)s>
                           <div class="articleBody">
                               %(img)s
                               %(text)s
                               %(more_link)s
                           </div>
                       </td></tr>
                    ''' % {'article_link': article_link,
                           'title': title,
                           'img': img,
                           'text': text,
                           'more_link': more_link,
                           'css_classes': ' '.join(css_classes),
                           'header_tag_size': header_tag_size}
            else:
                out += '''
                       <tr><td class="article">
                           <h%(header_tag_size)s class="%(css_classes)s articleTitle" style="clear:both;">
                               <a title="link to the article" href="%(article_link)s">%(title)s</a>&nbsp;&nbsp;
                               %(more_link)s
                           </h%(header_tag_size)s>
                           %(img)s
                       </td></tr>
                       ''' % {'article_link': article_link,
                              'title': title,
                              'more_link': more_link,
                              'img': img,
                              'css_classes': ' '.join(css_classes),
                              'header_tag_size': header_tag_size}
    out += '</table>'
    if verbose == 0 and not CFG_ACCESS_CONTROL_LEVEL_SITE == 2 :
        cache_index_page(out, journal_name, category_name,
                         this_issue_number, ln)

    return out
def format_element(bfo, latest_issue_only='yes', newest_articles_only='yes',
           link_category_headers='yes', display_categories='', hide_when_only_new_records="no"):
    """
    Display the index to the newest articles (of the latest issue, or of the displayed issue)

    @param latest_issue_only: if 'yes', always display articles of the latest issue, even if viewing a past issue
    @param newest_articles_only: only display new articles, not those that also appeared in previous issues
    @param link_category_headers: if yes, category headers link to index page of that category
    @param display_categories: comma-separated list of categories to display. If none, display all
    @param hide_when_only_new_records: if 'yes' display new articles only if old articles exist in this issue
    """
    args = parse_url_string(bfo.user_info['uri'])
    journal_name = args["journal_name"]
    ln = bfo.lang
    _ = gettext_set_language(ln)

    if latest_issue_only.lower() == 'yes':
        issue_number = get_current_issue(bfo.lang, journal_name)
    else:
        issue_number = args["issue"]

    # Try to get HTML from cache
    if args['verbose'] == 0:
        cached_html = _get_whatsNew_from_cache(journal_name, issue_number, ln)
        if cached_html:
            return cached_html

    # No cache? Build from scratch
    # 1. Get the articles
    journal_categories = get_journal_categories(journal_name,
                                                issue_number)
    if display_categories:
        display_categories = display_categories.lower().split(',')
        journal_categories = [category for category in journal_categories \
                              if category.lower() in display_categories]
    whats_new_articles = {}
    for category in journal_categories:
        whats_new_articles[category] = get_journal_articles(journal_name,
                                                            issue_number,
                                                            category,
                                                            newest_only=newest_articles_only.lower() == 'yes')

    # Do we want to display new articles only if they have been added
    # to an issue that contains non-new records?
    if hide_when_only_new_records.lower() == "yes":
        # First gather all articles in this issue
        all_whats_new_articles = {}
        for category in journal_categories:
            all_whats_new_articles[category] = get_journal_articles(journal_name,
                                                                    issue_number,
                                                                    category,
                                                                    newest_first=True,
                                                                    newest_only=False)
        # Then check if we have some articles at position > -1
        has_old_articles = False
        for articles in all_whats_new_articles.values():
            if len([order for order in articles.keys() if order > -1]) > 0:
                has_old_articles = True
                break
        if not has_old_articles:
            # We don't have old articles? Thend don't consider any
            for category in journal_categories:
                whats_new_articles[category] = {}

    # 2. Build the HTML
    html_out = _get_breaking_news(ln, journal_name)
    for category in journal_categories:
        articles_in_category = whats_new_articles[category]
        html_articles_in_category = ""
        # Generate the list of articles in this category
        order_numbers = articles_in_category.keys()
        order_numbers.sort()
        for order in order_numbers:
            articles = articles_in_category[order]
            for recid in articles:
                link = make_journal_url(bfo.user_info['uri'], {'journal_name': journal_name,
                                                               'issue_number': issue_number.split('/')[0],
                                                               'issue_year': issue_number.split('/')[1],
                                                               'category': category,
                                                               'recid': recid,
                                                               'ln': bfo.lang})
                temp_rec = BibFormatObject(recid)
                if ln == 'fr':
                    try:
                        title = temp_rec.fields('246_1a')[0]
                    except:
                        try:
                            title = temp_rec.field('245__a')
                        except:
                            continue
                else:
                    try:
                        title = temp_rec.field('245__a')
                    except:
                        continue
                try:
                    html_articles_in_category += '<li><a href="%s">%s</a></li>' % \
                                                 (link, title)
                except:
                    pass

        if html_articles_in_category:
            # Good, we found some new articles for this category.
            # Then insert the genereated results into a larger list
            # with category as "parent".
            html_out += '<li>'
            if link_category_headers.lower() == 'yes':
                html_out += '<a href="'
                html_out += make_journal_url(bfo.user_info['uri'],
                                             {'journal_name': journal_name,
                                              'issue_number': issue_number.split('/')[0],
                                              'issue_year': issue_number.split('/')[1],
                                              'category': category,
                                              'recid': '',
                                              'ln': bfo.lang})
                html_out += '" class="whatsNewCategory">%s</a>' % _(category)
            else:
                html_out += '<span class="whatsNewCategory">%s</span>' % _(category)

            html_out += '<ul class="whatsNewItem">'
            html_out += html_articles_in_category
            html_out += '</ul></li>'

    if not html_out:
        html_out = '<i>' + _('There are no new articles for the moment') + '</i>'
    else:
        html_out = '<ul class="whatsNew">' + html_out + '</ul>'

    if args['verbose'] == 0:
        cache_whatsNew(html_out, journal_name, issue_number, ln)

    return html_out
def format_element(bfo,
                   new_articles_first='yes',
                   subject_to_css_class_kb="WebJournalSubject2CSSClass",
                   display_all_category_articles='no',
                   display_category_title='no'):
    """
    List all articles one after the other, on the same page.

    Similar to bfe_webjournal_articles_overview, but displays full articles.

    Note that you cannot use both bfe_webjournal_articles_overview and
    bfe_webjournal_articles: you have to choose one of them, as they
    use the same cache location (It would also not make sense to use
    both...).

    @param new_articles_first: if 'yes', display new articles before other articles
    @param subject_to_css_class_kb: knowledge base that maps 595__a to a CSS class
    @param display_all_category_articles: if yes, display all articles, whatever category is selected
    @param display_category_title: if yes, display category title (useful if display_all_category_articles is enabled)

    @see: bfe_webjournal_articles_overview.py
    """
    args = parse_url_string(bfo.user_info['uri'])
    journal_name = args["journal_name"]
    this_issue_number = args["issue"]
    category_name = args["category"]
    verbose = args["verbose"]
    ln = bfo.lang
    _ = gettext_set_language(ln)

    # Try to get the page from cache. Only if issue is older or equal
    # to latest release.
    latest_released_issue = get_current_issue(ln, journal_name)
    if verbose == 0 and not issue_is_later_than(this_issue_number,
                                                latest_released_issue):
        cached_html = get_index_page_from_cache(journal_name, category_name,
                                                this_issue_number, ln)
        if cached_html:
            return cached_html

    # Shall we display current category, or all?
    categories = [category_name]
    if display_all_category_articles.lower() == 'yes':
        categories = get_journal_categories(journal_name, this_issue_number)

    out = ''
    for category_name in categories:
        if display_category_title.lower() == 'yes':
            out += '<h2>' + _(category_name) + '</h2>'

        out += '<table border="0" cellpadding="0" cellspacing="0">'
        # Get the id list
        ordered_articles = get_journal_articles(
            journal_name,
            this_issue_number,
            category_name,
            newest_first=new_articles_first.lower() == 'yes')
        new_articles_only = False
        if ordered_articles.keys() and max(ordered_articles.keys()) < 0:
            # If there are only new articles, don't bother marking them as
            # new
            new_articles_only = True

        order_numbers = ordered_articles.keys()
        order_numbers.sort()

        for order_number in order_numbers:
            for article_id in ordered_articles[order_number]:
                # A record is considered as new if its position is
                # negative and there are some non-new articles
                article_is_new = (order_number < 0 and not new_articles_only)

                temp_rec = BibFormatObject(article_id)
                title = ''
                if ln == "fr":
                    title = temp_rec.field('246_1a')
                    if title == '':
                        title = temp_rec.field('245__a')
                else:
                    title = temp_rec.field('245__a')
                    if title == '':
                        title = temp_rec.field('246_1a')

                # Get CSS class (if relevant)
                notes = temp_rec.fields('595__a')
                css_classes = [temp_rec.kb(subject_to_css_class_kb, note, None) \
                               for note in notes]
                css_classes = [css_class for css_class in css_classes \
                               if css_class is not None]

                if article_is_new:
                    css_classes.append('new')

                # Finally create the output. Two different outputs
                # depending on if we have text to display or not
                text = []
                if ln == "fr":
                    text = temp_rec.fields('590__b')
                    if not text or \
                           (len(text) == 1 and \
                            (text[0].strip() in ['', '<br />', '<!--HTML--><br />'])):
                        text = temp_rec.fields('520__b')
                else:
                    text = temp_rec.fields('520__b')
                    if not text or \
                           (len(text) == 1 and \
                            (text[0].strip() in ['', '<br />', '<!--HTML--><br />'])):
                        text = temp_rec.fields('590__b')
                text = '<br/>'.join(text)

                out += '''
                            <tr><td class="article">
                               <h%(header_tag_size)s class="%(css_classes)s articleTitle" style="clear:both;">
                                   %(title)s
                               </h%(header_tag_size)s>
                               <div class="articleBody">
                                   <div class="articleText">
                                      %(text)s
                                   </div>
                               </div>
                           </td></tr>
                        ''' % {
                    'title':
                    title,
                    'text':
                    text,
                    'header_tag_size':
                    (display_category_title.lower() == 'yes') and '3' or '2',
                    'css_classes':
                    ' '.join(css_classes)
                }
        out += '</table>'

    if verbose == 0 and not CFG_ACCESS_CONTROL_LEVEL_SITE == 2:
        cache_index_page(out, journal_name, category_name, this_issue_number,
                         ln)

    return out
Beispiel #29
0
def format_element(bfo, limit, separator='; ',
                   extension='[...]',
                   print_links="yes",
                   print_affiliations='no',
                   affiliation_prefix=' (',
                   affiliation_suffix=')',
                   print_affiliation_first='no',
                   interactive="no",
                   highlight="no",
                   affiliations_separator=" ; ",
                   name_last_first="yes",
                   collaboration="yes",
                   id_links="no",
                   markup="html",
                   link_extension="no",
                   suffix=''
                   ):
    """
    Prints the list of authors of a record.

    @param limit the maximum number of authors to display
    @param separator the separator between authors.
    @param extension a text printed if more authors than 'limit' exist
    @param print_links if yes, prints the authors as HTML link to their publications
    @param print_affiliations if yes, make each author name followed by its affiliation
    @param affiliation_prefix prefix printed before each affiliation
    @param affiliation_suffix suffix printed after each affiliation
    @param print_affiliation_first if 'yes', affiliation is printed before the author
    @param interactive if yes, enable user to show/hide authors when there are too many (html + javascript)
    @param highlight highlights authors corresponding to search query if set to 'yes'
    @param affiliations_separator separates affiliation groups
    @param name_last_first if yes (default) print last, first  otherwise first last
    @param collaboration if yes (default) uses collaboration name in place of long author list, if available
    @param id_links if yes (default = no) prints link based on INSPIRE IDs if available - only used if print_links = yes
    @param markup html (default) or latex controls small markup differences
    @param link_extension if 'yes' link the extension to the detailed
    record page

    """
    from urllib import quote
    from cgi import escape
    import re
    from invenio.base.i18n import gettext_set_language
    from invenio.config import CFG_BASE_URL, CFG_SITE_RECORD
    from invenio.modules.formatter.engine import BibFormatObject

    _ = gettext_set_language(bfo.lang)    # load the right message language

    #regex for parsing last and first names and initials
    re_last_first = re.compile('^(?P<last>[^,]+)\s*,\s*(?P<first_names>[^\,]*)(?P<extension>\,?.*)$')
    re_initials = re.compile(r'(?P<initial>\w)(\w+|\.)\s*')
    re_coll = re.compile(r'\s*collaborations?', re.IGNORECASE)

    bibrec_id = bfo.control_field("001")
    authors = []
    lastauthor = ''

    # HepData and only-INSPIRE data records inherit the list of authors from the original paper
    if (bfo.field("520__9") == "HEPDATA") or (bfo.field("520__9") == "INSPIRE"):
        parent_recid = bfo.field("786__w")
        bfo_parent = BibFormatObject(int(parent_recid))

        authors = []
        authors_1 = bfo_parent.fields('100__', repeatable_subfields_p=True)
        authors_2 = bfo_parent.fields('700__', repeatable_subfields_p=True)
    # other datasources should have a list of authors
    else:
        authors = []
        authors_1 = bfo.fields('100__', repeatable_subfields_p=True)
        authors_2 = bfo.fields('700__', repeatable_subfields_p=True)

    authors.extend(authors_1)
    authors.extend(authors_2)

    # If there are no author check for corporate author in 110__a field
    if len(authors) == 0:
        authors = bfo.fields('110__', repeatable_subfields_p=True)
        # For corporate authors we don't want to reverse names order
        name_last_first = 'yes'
        # And we don't want to create links
        print_links = 'no'

    # Keep real num of authors. fix + affiliations_separator.join(author['u']) + \
    nb_authors = len(authors)

    # Limit num of authors, so that we do not process
    # the authors that will not be shown. This can only
    # be done in non-interactive mode, as interactive mode
    # allows to show all of them.
    if limit.isdigit() and nb_authors > int(limit) \
           and interactive != "yes":
        if bfo.field('710g'):   # check for colln note
            authors = authors[:1]
        else:

            authors = authors[:int(limit)]

    # Process authors to add link, affiliation and highlight
    for author in authors:

        if author.has_key('a'):
            author['a'] = author['a'][0]  # There should not be
                                          # repeatable subfields here.
            if highlight == 'yes':
                from invenio import bibformat_utils
                author['a'] = bibformat_utils.highlight(author['a'],
                                                        bfo.search_pattern)

            #check if we need to reverse last, first
            #we don't try to reverse it if it isn't stored with a comma.
            first_last_match = re_last_first.search(author['a'])
            author['display'] = author['a']

            if name_last_first.lower() == "no":
                if first_last_match:
                    author['display'] = first_last_match.group('first_names') + \
                                        ' ' + \
                                        first_last_match.group('last') + \
                                        first_last_match.group('extension')

            #for latex we do initials only  (asn assume first last)
            if markup == 'latex':
                if first_last_match:
                    first = re_initials.sub('\g<initial>.~', \
                                        first_last_match.group('first_names'))
                    author['display'] = first  + \
                                        first_last_match.group('last') + \
                                        first_last_match.group('extension')


            if print_links.lower() == "yes":

                # if there is an ID, search using that.
                id_link = ''
                if id_links == "yes" and author.has_key('i'):
                    author['i'] = author['i'][0]  #possible to have more IDs?
                    id_link = '<a class="authoridlink" href="' + \
                              CFG_BASE_URL + \
                              '/search?' + \
                              'ln='+ bfo.lang + \
                              '&amp;p=100__i' + escape(':' + author['i']) + \
                              '+or+700__i' + escape(':' + author['i']) +\
                              '">'+escape("(ID Search)") + '</a> '


                author['display'] = '<a class="authorlink" href="' + \
                                    CFG_BASE_URL + \
                                    '/author/'+ quote(author['a']) + \
                                    '?recid=' + bibrec_id + \
                                    '&amp;ln='+ bfo.lang + \
                                    '">' + escape(author['display'])+'</a>' + \
                                    id_link

        if print_affiliations == "yes":
            if author.has_key('e'):
                author['e'] = affiliation_prefix + \
                              affiliations_separator.join(author['e']) + \
                              affiliation_suffix



            if author.has_key('u'):
                author['ilink'] = ['<a class="afflink" href="' + \
                                   CFG_BASE_URL + '/search?cc=Institutions&amp;p=institution:'+ \
                                   quote('"' + string + '"') + \
                                   '&amp;ln=' + bfo.lang + \
                                   '">' + \
                                   string.lstrip() + \
                                   '</a>' for string in author['u']]
                author['u'] = affiliation_prefix + \
                              affiliations_separator.join(author['ilink']) + \
                              affiliation_suffix

#
#  Consolidate repeated affiliations
#
    last = ''
    authors.reverse()
    for author in authors:
        if not author.has_key('u'):
            author['u'] = ''
        #print 'this->'+ author['a']+'\n'
        if last == author['u']:
            author['u'] = ''
        else:
            last = author['u']

    authors.reverse()

    # Flatten author instances
    if print_affiliations == 'yes':
#      100__a (100__e)  700__a (100__e) (100__u)
        if print_affiliation_first.lower() != 'yes':
            authors = [author.get('display', '') + author.get('e', '') + author.get('u', '')
                       for author in authors]

        else:
            authors = [author.get('u', '') + author.get('display', '')
                       for author in authors]

    else:
        authors = [author.get('display', '')
                   for author in authors]

    # link the extension to detailed record
    if link_extension == 'yes' and interactive != 'yes':
        extension = '<a class="authorlink" href="' +  \
                    CFG_BASE_URL + '/' + CFG_SITE_RECORD + '/' + str(bfo.recID) + '">' + \
                    extension + '</a>'

    # Detect Collaborations:
    if collaboration == "yes":
        colls = []
        for coll in bfo.fields("710__g"):
            if coll not in colls:
                colls.append(coll)
    else:
        colls = []
    if colls:
        short_coll = False
        colls = [re_coll.sub('', coll) for coll in colls]
        if print_links.lower() == "yes":
            colls = ['<a class="authorlink" href="' +
                     CFG_BASE_URL + '/search' +
                     '?p=collaboration:' + quote("'" + coll + "'") +
                     '&amp;ln=' + bfo.lang +
                     '">'+escape(coll)+'</a>' for coll in colls]

        coll_display = " and ".join(colls)
        if not coll_display.endswith("aboration"):
            coll_display += " Collaboration"
            if len(colls) > 1:
                coll_display += 's'
        if nb_authors > 1:
            if markup == 'latex':
                coll_display =  authors[0] + extension + "  [" + \
                               coll_display + "]"
            elif interactive == "yes":
                coll_display += " ("  + authors[0] + " "
                extension += ")"
            else:  #html
                coll_display += " (" + authors[0] + extension + ")"
        elif nb_authors == 1:
            short_coll = True
            if markup == 'latex':
                coll_display = authors[0] + " [" + coll_display + "]"
            else:  #html
                coll_display += " (" + authors[0] + " for the collaboration)"
        elif nb_authors == 0:
            short_coll = True
            if markup == 'latex':
                coll_display = "[" + coll_display + "]"

    # Start outputting, depending on options and number of authors
    if colls and (interactive != "yes" or short_coll):
        return coll_display

    if limit.isdigit() and nb_authors > int(limit) and interactive != "yes":
        if markup == 'latex':
            lastauthor = authors.pop()
            lastauthor = ' and ' + lastauthor
            limit = int(limit) - 1

        return separator.join(authors[:int(limit)]) + lastauthor + \
               extension

    elif interactive == "yes" and ((colls and not short_coll) or (limit.isdigit() and nb_authors > int(limit))):
        out = '''
        <script>
        function toggle_authors_visibility(){
            var more = document.getElementById('more');
            var link = document.getElementById('link');
            var extension = document.getElementById('extension');
            if (more.style.display=='none'){
                more.style.display = '';
                extension.style.display = 'none';
                link.innerHTML = "%(show_less)s"
            } else {
                more.style.display = 'none';
                extension.style.display = '';
                link.innerHTML = "%(show_more)s"
            }
            link.style.color = "rgb(204,0,0);"
        }

        function set_up(){
            var extension = document.getElementById('extension');
            extension.innerHTML = '%(extension)s';
            toggle_authors_visibility();
        }

        </script>
        ''' % {'show_less': _("Hide"),
               'show_more': _("Show all %(x_num_of_authors)i authors", x_num_of_authors=nb_authors),
               'extension': extension}

#        out += '<a name="show_hide" />'
        if colls:
            show = coll_display
            more = separator + separator.join(authors[1:]) + ')'
        else:
            show = separator.join(authors[:int(limit)])
            more = separator.join(authors[int(limit):len(authors)])

        out += show
        out += ' <span id="more" style="">' + more + '</span>'
        out += ' <span id="extension"></span>'
        out += ' <small><i><a id="link" href="#"' + \
               ' style="color:green;background:white;" onclick="toggle_authors_visibility()" ' + \
               ' style="color:rgb(204,0,0);"></a></i></small>'
        out += '<script>set_up()</script>'
        return out
    elif nb_authors > 0:
        if markup == 'latex' and nb_authors > 1:
            lastauthor = authors.pop()
            lastauthor = ' and ' + lastauthor
        output = separator.join(authors) + lastauthor
        # remove the dot from the end of authors list when the suffix starts with dot
        # (to avoid two consecutive dots)
        if suffix and output and output[-1] == suffix[0] == '.':
            output = output[:-1]
        return output
Beispiel #30
0
def format_marcxml_file(marcxml, is_file=False):
    '''
        Parse the given marcxml file to retreive the metadata needed by the
        forward of the document to ArXiv.org
        @param marcxml: marxml file that contains metadata from Invenio
        @return: (dictionnary) couple of key value needed for the push
    '''

    #init the return tuple
    marcxml_values = {
        'id': '',
        'title': '',
        'summary': '',
        'contributors': [],
        'journal_refs': [],
        'report_nos': [],
        'comment': '',
        'doi': ''
    }

    # check if the marcxml is not empty
    if marcxml == '':
        marcxml_values['error'] = "MARCXML string is empty !"
        return marcxml_values

    #get the tag id and code from tag table
    main_report_number = CFG_MARC_REPORT_NUMBER
    add_report_number = CFG_MARC_ADDITIONAL_REPORT_NUMBER
    main_title = CFG_MARC_TITLE
    main_summary = CFG_MARC_ABSTRACT
    main_author = CFG_MARC_AUTHOR_NAME
    main_author_affiliation = CFG_MARC_AUTHOR_AFFILIATION
    add_author = CFG_MARC_CONTRIBUTOR_NAME
    add_author_affiliation = CFG_MARC_CONTRIBUTOR_AFFILIATION
    main_comment = CFG_MARC_COMMENT
    doi = CFG_MARC_DOI
    journal_ref_code = CFG_MARC_JOURNAL_REF_CODE
    journal_ref_title = CFG_MARC_JOURNAL_REF_TITLE
    journal_ref_page = CFG_MARC_JOURNAL_REF_PAGE
    journal_ref_year = CFG_MARC_JOURNAL_REF_YEAR

    #init tmp values
    contributor = {'name': '', 'email': '', 'affiliation': []}

    try:
        bfo = BibFormatObject(recID=None, xml_record=marcxml)
    except:
        marcxml_values['error'] = "Unable to open marcxml file !"
        return marcxml_values

    marcxml_values = {
        'id': bfo.field(main_report_number),
        'title': bfo.field(main_title),
        'summary': bfo.field(main_summary),
        'report_nos': bfo.fields(add_report_number),
        'contributors': [],
        'journal_refs': [],
        'comment': bfo.field(main_comment),
        'doi': bfo.field(doi)
    }

    authors = bfo.fields(main_author[:-1], repeatable_subfields_p=True)
    for author in authors:
        name = author.get(main_author[-1], [''])[0]
        affiliation = author.get(main_author_affiliation[-1], [])
        author = {'name': name, 'email': '', 'affiliation': affiliation}
        marcxml_values['contributors'].append(author)

    authors = bfo.fields(add_author[:-1], repeatable_subfields_p=True)
    for author in authors:
        name = author.get(add_author[-1], [''])[0]
        affiliation = author.get(add_author_affiliation[-1], [])
        author = {'name': name, 'email': '', 'affiliation': affiliation}
        marcxml_values['contributors'].append(author)

    journals = bfo.fields(journal_ref_title[:-1])
    for journal in journals:
        journal_title = journal.get(journal_ref_title[-1], '')
        journal_page = journal.get(journal_ref_page[-1], '')
        journal_code = journal.get(journal_ref_code[-1], '')
        journal_year = journal.get(journal_ref_year[-1], '')
        journal = "%s: %s (%s) pp. %s" % (journal_title, journal_code,
                                          journal_year, journal_page)
        marcxml_values['journal_refs'].append(journal)

    return marcxml_values
Beispiel #31
0
def format_marcxml_file(marcxml, is_file=False):
    '''
        Parse the given marcxml file to retreive the metadata needed by the
        forward of the document to ArXiv.org
        @param marcxml: marxml file that contains metadata from Invenio
        @return: (dictionnary) couple of key value needed for the push
    '''

    #init the return tuple
    marcxml_values = { 'id'            : '',
                       'title'         : '',
                       'summary'       : '',
                       'contributors'  : [],
                       'journal_refs'  : [],
                       'report_nos'    : [],
                       'comment'       : '',
                       'doi'           : '' }

    # check if the marcxml is not empty
    if marcxml == '':
        marcxml_values['error'] = "MARCXML string is empty !"
        return marcxml_values

    #get the tag id and code from tag table
    main_report_number = CFG_MARC_REPORT_NUMBER
    add_report_number = CFG_MARC_ADDITIONAL_REPORT_NUMBER
    main_title = CFG_MARC_TITLE
    main_summary = CFG_MARC_ABSTRACT
    main_author = CFG_MARC_AUTHOR_NAME
    main_author_affiliation = CFG_MARC_AUTHOR_AFFILIATION
    add_author = CFG_MARC_CONTRIBUTOR_NAME
    add_author_affiliation = CFG_MARC_CONTRIBUTOR_AFFILIATION
    main_comment = CFG_MARC_COMMENT
    doi = CFG_MARC_DOI
    journal_ref_code = CFG_MARC_JOURNAL_REF_CODE
    journal_ref_title = CFG_MARC_JOURNAL_REF_TITLE
    journal_ref_page = CFG_MARC_JOURNAL_REF_PAGE
    journal_ref_year = CFG_MARC_JOURNAL_REF_YEAR

    #init tmp values
    contributor = {'name' : '', 'email' : '', 'affiliation' : []}

    try:
        bfo = BibFormatObject(recID=None, xml_record=marcxml)
    except:
        marcxml_values['error'] = "Unable to open marcxml file !"
        return marcxml_values

    marcxml_values = { 'id'           : bfo.field(main_report_number),
                       'title'        : bfo.field(main_title),
                       'summary'      : bfo.field(main_summary),
                       'report_nos'   : bfo.fields(add_report_number),
                       'contributors' : [],
                       'journal_refs' : [],
                       'comment'      : bfo.field(main_comment),
                       'doi'          : bfo.field(doi)}

    authors = bfo.fields(main_author[:-1], repeatable_subfields_p=True)
    for author in authors:
        name = author.get(main_author[-1], [''])[0]
        affiliation = author.get(main_author_affiliation[-1], [])
        author = {'name': name, 'email': '', 'affiliation': affiliation}
        marcxml_values['contributors'].append(author)

    authors = bfo.fields(add_author[:-1], repeatable_subfields_p=True)
    for author in authors:
        name = author.get(add_author[-1], [''])[0]
        affiliation = author.get(add_author_affiliation[-1], [])
        author = {'name': name, 'email': '', 'affiliation': affiliation}
        marcxml_values['contributors'].append(author)

    journals = bfo.fields(journal_ref_title[:-1])
    for journal in journals:
        journal_title = journal.get(journal_ref_title[-1], '')
        journal_page = journal.get(journal_ref_page[-1], '')
        journal_code = journal.get(journal_ref_code[-1], '')
        journal_year = journal.get(journal_ref_year[-1], '')
        journal = "%s: %s (%s) pp. %s" % (journal_title, journal_code, journal_year, journal_page)
        marcxml_values['journal_refs'].append(journal)

    return marcxml_values