# coding: utf-8

import logging
import requests
import mimetypes
from io import BytesIO
from urllib.parse import urlparse
from datetime import datetime, timedelta
from collections import OrderedDict
from flask_babelex import gettext as _
from flask import (
    render_template,
    abort,
    current_app,
    request,
    session,
    redirect,
    jsonify,
    url_for,
    Response,
    send_from_directory,
    g,
    make_response,
)
from werkzeug.contrib.atom import AtomFeed
from urllib.parse import urljoin
from legendarium.formatter import descriptive_short_format

from . import main
from webapp import babel
from webapp import cache
from webapp import controllers
from webapp.choices import STUDY_AREAS
from webapp.utils import utils
from webapp.utils.caching import cache_key_with_lang, cache_key_with_lang_with_qs
from webapp import forms

from webapp.config.lang_names import display_original_lang_name

from opac_schema.v1.models import Journal, Issue, Article, Collection

from lxml import etree
from packtools import HTMLGenerator

logger = logging.getLogger(__name__)

JOURNAL_UNPUBLISH = _("O periódico está indisponível por motivo de: ")
ISSUE_UNPUBLISH = _("O número está indisponível por motivo de: ")
ARTICLE_UNPUBLISH = _("O artigo está indisponível por motivo de: ")

IAHX_LANGS = dict(
    p='pt',
    e='es',
    i='en',
)


def url_external(endpoint, **kwargs):
    url = url_for(endpoint, **kwargs)
    return urljoin(request.url_root, url)


class RetryableError(Exception):
    """Erro recuperável sem que seja necessário modificar o estado dos dados
    na parte cliente, e.g., timeouts, erros advindos de particionamento de rede
    etc.
    """


class NonRetryableError(Exception):
    """Erro do qual não pode ser recuperado sem modificar o estado dos dados
    na parte cliente, e.g., recurso solicitado não exite, URI inválida etc.
    """


def fetch_data(url: str, timeout: float = 2) -> bytes:
    try:
        response = requests.get(url, timeout=timeout)
    except (requests.ConnectionError, requests.Timeout) as exc:
        raise RetryableError(exc) from exc
    except (requests.InvalidSchema, requests.MissingSchema, requests.InvalidURL) as exc:
        raise NonRetryableError(exc) from exc
    else:
        try:
            response.raise_for_status()
        except requests.HTTPError as exc:
            if 400 <= exc.response.status_code < 500:
                raise NonRetryableError(exc) from exc
            elif 500 <= exc.response.status_code < 600:
                raise RetryableError(exc) from exc
            else:
                raise

    return response.content


@main.before_app_request
def add_collection_to_g():

    if not hasattr(g, 'collection'):
        try:
            collection = controllers.get_current_collection()
            setattr(g, 'collection', collection)
        except Exception:
            # discutir o que fazer aqui
            setattr(g, 'collection', {})


@main.after_request
def add_header(response):
    response.headers['x-content-type-options'] = 'nosniff'
    return response

@main.after_request
def add_language_code(response):
    language = session.get('lang', get_locale())
    response.set_cookie('language', language)
    return response


@main.before_app_request
def add_forms_to_g():
    setattr(g, 'email_share', forms.EmailShareForm())
    setattr(g, 'email_contact', forms.ContactForm())
    setattr(g, 'error', forms.ErrorForm())


@main.before_app_request
def add_scielo_org_config_to_g():
    language = session.get('lang', get_locale())
    scielo_org_links = {
        key: url[language]
        for key, url in current_app.config.get('SCIELO_ORG_URIS', {}).items()
    }
    setattr(g, 'scielo_org', scielo_org_links)


@babel.localeselector
def get_locale():
    langs = current_app.config.get('LANGUAGES')
    lang_from_headers = request.accept_languages.best_match(list(langs.keys()))

    if 'lang' not in list(session.keys()):
        session['lang'] = lang_from_headers

    if not lang_from_headers and not session['lang']:
        # Caso não seja possível detectar o idioma e não tenhamos a chave lang
        # no seção, fixamos o idioma padrão.
        session['lang'] = current_app.config.get('BABEL_DEFAULT_LOCALE')

    return session['lang']


@main.route('/set_locale/<string:lang_code>/')
def set_locale(lang_code):
    langs = current_app.config.get('LANGUAGES')

    if lang_code not in list(langs.keys()):
        abort(400, _('Código de idioma inválido'))

    referrer = request.referrer
    hash = request.args.get('hash')
    if hash:
        referrer += "#" + hash

    # salvar o lang code na sessão
    session['lang'] = lang_code
    return redirect(referrer)


def get_lang_from_session():
    """
    Tenta retornar o idioma da seção, caso não consiga retorna
    BABEL_DEFAULT_LOCALE.
    """
    try:
        return session['lang']
    except KeyError:
        return current_app.config.get('BABEL_DEFAULT_LOCALE')


@main.route('/')
@cache.cached(key_prefix=cache_key_with_lang)
def index():
    language = session.get('lang', get_locale())
    news = controllers.get_latest_news_by_lang(language)

    tweets = controllers.get_collection_tweets()
    press_releases = controllers.get_press_releases({'language': language})

    urls = {
        'downloads': '{0}/w/accesses?collection={1}'.format(
            current_app.config['METRICS_URL'],
            current_app.config['OPAC_COLLECTION']),
        'references': '{0}/w/publication/size?collection={1}'.format(
            current_app.config['METRICS_URL'],
            current_app.config['OPAC_COLLECTION']),
        'other': '{0}/?collection={1}'.format(
            current_app.config['METRICS_URL'],
            current_app.config['OPAC_COLLECTION'])
    }

    if (
        g.collection is not None
        and isinstance(g.collection, Collection)
        and g.collection.metrics is not None
        and current_app.config['USE_HOME_METRICS']
    ):
        g.collection.metrics.total_journal = Journal.objects.filter(
            is_public=True, current_status="current"
        ).count()
        g.collection.metrics.total_article = Article.objects.filter(
            is_public=True
        ).count()

    context = {
        'news': news,
        'urls': urls,
        'tweets': tweets,
        'press_releases': press_releases,
    }

    return render_template("collection/index.html", **context)


# ##################################Collection###################################


@main.route('/journals/alpha')
@cache.cached(key_prefix=cache_key_with_lang)
def collection_list():
    allowed_filters = ["current", "no-current", ""]
    query_filter = request.args.get("status", "")

    if not query_filter in allowed_filters:
        query_filter = ""

    journals_list = [
        controllers.get_journal_json_data(journal)
        for journal in controllers.get_journals(query_filter=query_filter)
    ]

    return render_template("collection/list_journal.html",
                           **{'journals_list': journals_list, 'query_filter': query_filter})


@main.route("/journals/thematic")
@cache.cached(key_prefix=cache_key_with_lang)
def collection_list_thematic():
    allowed_query_filters = ["current", "no-current", ""]
    allowed_thematic_filters = ["areas", "wos", "publisher"]
    thematic_table = {
        "areas": "study_areas",
        "wos": "subject_categories",
        "publisher": "publisher_name",
    }
    query_filter = request.args.get("status", "")
    title_query = request.args.get("query", "")
    thematic_filter = request.args.get("filter", "areas")

    if not query_filter in allowed_query_filters:
        query_filter = ""

    if not thematic_filter in allowed_thematic_filters:
        thematic_filter = "areas"

    lang = get_lang_from_session()[:2].lower()
    objects = controllers.get_journals_grouped_by(
        thematic_table[thematic_filter],
        title_query,
        query_filter=query_filter,
        lang=lang,
    )

    return render_template(
        "collection/list_thematic.html",
        **{"objects": objects, "query_filter": query_filter, "filter": thematic_filter}
    )


@main.route('/journals/feed/')
@cache.cached(key_prefix=cache_key_with_lang)
def collection_list_feed():
    language = session.get('lang', get_locale())
    collection = controllers.get_current_collection()

    title = 'SciELO - %s - %s' % (collection.name, _('Últimos periódicos inseridos na coleção'))
    subtitle = _('10 últimos periódicos inseridos na coleção %s' % collection.name)

    feed = AtomFeed(title,
                    subtitle=subtitle,
                    feed_url=request.url, url=request.url_root)

    journals = controllers.get_journals_paginated(
        title_query='', page=1, order_by='-created', per_page=10)

    if not journals.items:
        feed.add('Nenhum periódico encontrado',
                 url=request.url,
                 updated=datetime.now())

    for journal in journals.items:
        issues = controllers.get_issues_by_jid(journal.jid, is_public=True)
        last_issue = issues[0] if issues else None

        articles = []
        if last_issue:
            articles = controllers.get_articles_by_iid(last_issue.iid,
                                                       is_public=True)

        result_dict = OrderedDict()
        for article in articles:
            section = article.get_section_by_lang(language[:2])
            result_dict.setdefault(section, [])
            result_dict[section].append(article)

        context = {
            'journal': journal,
            'articles': result_dict,
            'language': language,
            'last_issue': last_issue
        }

        feed.add(journal.title,
                 render_template("collection/list_feed_content.html", **context),
                 content_type='html',
                 author=journal.publisher_name,
                 url=url_external('main.journal_detail', url_seg=journal.url_segment),
                 updated=journal.updated,
                 published=journal.created)

    return feed.get_response()


@main.route("/about/", methods=['GET'])
@main.route('/about/<string:slug_name>', methods=['GET'])
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def about_collection(slug_name=None):
    language = session.get('lang', get_locale())

    context = {}
    page = None
    if slug_name:
        # caso seja uma página
        page = controllers.get_page_by_slug_name(slug_name, language)
        if not page:
            abort(404, _('Página não encontrada'))
        context['page'] = page
    else:
        # caso não seja uma página é uma lista
        pages = controllers.get_pages_by_lang(language)
        context['pages'] = pages

    return render_template("collection/about.html", **context)


# ###################################Journal#####################################


@main.route('/scielo.php/')
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def router_legacy():

    script_php = request.args.get('script', None)
    pid = request.args.get('pid', None)
    tlng = request.args.get('tlng', None)
    allowed_scripts = [
        'sci_serial', 'sci_issuetoc', 'sci_arttext', 'sci_abstract', 'sci_issues', 'sci_pdf'
    ]
    if (script_php is not None) and (script_php in allowed_scripts) and not pid:
        # se tem pelo menos um param: pid ou script_php
        abort(400, _(u'Requsição inválida ao tentar acessar o artigo com pid: %s' % pid))
    elif script_php and pid:

        if script_php == 'sci_serial':
            # pid = issn
            journal = controllers.get_journal_by_issn(pid)

            if not journal:
                abort(404, _('Periódico não encontrado'))

            if not journal.is_public:
                abort(404, JOURNAL_UNPUBLISH + _(journal.unpublish_reason))

            return redirect(url_for('main.journal_detail',
                            url_seg=journal.url_segment), code=301)

        elif script_php == 'sci_issuetoc':

            issue = controllers.get_issue_by_pid(pid)

            if not issue:
                abort(404, _('Número não encontrado'))

            if not issue.is_public:
                abort(404, ISSUE_UNPUBLISH + _(issue.unpublish_reason))

            if not issue.journal.is_public:
                abort(404, JOURNAL_UNPUBLISH + _(issue.journal.unpublish_reason))

            if issue.url_segment and "ahead" in issue.url_segment:
                return redirect(
                    url_for('main.aop_toc', url_seg=url_seg), code=301)

            return redirect(
                url_for(
                    "main.issue_toc",
                    url_seg=issue.journal.url_segment,
                    url_seg_issue=issue.url_segment),
                301
            )

        elif script_php == 'sci_arttext' or script_php == 'sci_abstract':
            article = controllers.get_article_by_pid_v2(pid)
            if not article:
                abort(404, _('Artigo não encontrado'))

            # 'abstract' or None (not False, porque False converterá a string 'False')
            part = (script_php == 'sci_abstract' and 'abstract') or None

            if tlng not in article.languages:
                tlng = article.original_language

            return redirect(url_for('main.article_detail_v3',
                                    url_seg=article.journal.url_segment,
                                    article_pid_v3=article.aid,
                                    part=part,
                                    lang=tlng),
                            code=301)

        elif script_php == 'sci_issues':

            journal = controllers.get_journal_by_issn(pid)

            if not journal:
                abort(404, _('Periódico não encontrado'))

            if not journal.is_public:
                abort(404, JOURNAL_UNPUBLISH + _(journal.unpublish_reason))

            return redirect(url_for('main.issue_grid',
                                    url_seg=journal.url_segment), 301)

        elif script_php == 'sci_pdf':
            # accesso ao pdf do artigo:
            article = controllers.get_article_by_pid_v2(pid)
            if not article:
                abort(404, _('Artigo não encontrado'))

            return redirect(
                url_for(
                    'main.article_detail_v3',
                    url_seg=article.journal.url_segment,
                    article_pid_v3=article.aid,
                    format='pdf',
                ),
                code=301
            )

        else:
            abort(400, _(u'Requsição inválida ao tentar acessar o artigo com pid: %s' % pid))

    else:
        return redirect('/')


@main.route('/<string:journal_seg>')
@main.route('/journal/<string:journal_seg>')
def journal_detail_legacy_url(journal_seg):
    return redirect(url_for('main.journal_detail',
                            url_seg=journal_seg), code=301)


@main.route('/j/<string:url_seg>/')
@cache.cached(key_prefix=cache_key_with_lang)
def journal_detail(url_seg):
    journal = controllers.get_journal_by_url_seg(url_seg)

    if not journal:
        abort(404, _('Periódico não encontrado'))

    if not journal.is_public:
        abort(404, JOURNAL_UNPUBLISH + _(journal.unpublish_reason))

    utils.fix_journal_last_issue(journal)

    # todo: ajustar para que seja só noticias relacionadas ao periódico
    language = session.get('lang', get_locale())
    news = controllers.get_latest_news_by_lang(language)

    # Press releases
    press_releases = controllers.get_press_releases({
        'journal': journal,
        'language': language})

    # Lista de seções
    # Mantendo sempre o idioma inglês para as seções na página incial do periódico
    if journal.last_issue and journal.current_status == "current":
        sections = [section for section in journal.last_issue.sections if section.language == 'en']
        recent_articles = controllers.get_recent_articles_of_issue(journal.last_issue.iid, is_public=True)
    else:
        sections = []
        recent_articles = []

    latest_issue = journal.last_issue

    if latest_issue:
        latest_issue_legend = descriptive_short_format(
            title=journal.title, short_title=journal.short_title,
            pubdate=str(latest_issue.year), volume=latest_issue.volume, number=latest_issue.number,
            suppl=latest_issue.suppl_text, language=language[:2].lower())
    else:
        latest_issue_legend = ''

    journal_metrics = controllers.get_journal_metrics(journal)

    context = {
        'journal': journal,
        'press_releases': press_releases,
        'recent_articles': recent_articles,
        'journal_study_areas': [
            STUDY_AREAS.get(study_area.upper()) for study_area in journal.study_areas
        ],
        # o primiero item da lista é o último número.
        # condicional para verificar se issues contém itens
        'last_issue': latest_issue,
        'latest_issue_legend': latest_issue_legend,
        'sections': sections if sections else None,
        'news': news,
        'journal_metrics': journal_metrics
    }

    return render_template("journal/detail.html", **context)


@main.route('/journal/<string:url_seg>/feed/')
@cache.cached(key_prefix=cache_key_with_lang)
def journal_feed(url_seg):
    journal = controllers.get_journal_by_url_seg(url_seg)

    if not journal:
        abort(404, _('Periódico não encontrado'))

    if not journal.is_public:
        abort(404, JOURNAL_UNPUBLISH + _(journal.unpublish_reason))

    issues = controllers.get_issues_by_jid(journal.jid, is_public=True)
    last_issue = issues[0] if issues else None
    articles = controllers.get_articles_by_iid(last_issue.iid, is_public=True)

    feed = AtomFeed(journal.title,
                    feed_url=request.url,
                    url=request.url_root,
                    subtitle=utils.get_label_issue(last_issue))

    feed_language = session.get('lang', get_locale())
    feed_language = feed_language[:2].lower()

    for article in articles:

        # ######### TODO: Revisar #########
        article_lang = feed_language
        if feed_language not in article.languages:
            article_lang = article.original_language

        feed.add(article.title or _('Artigo sem título'),
                 render_template("issue/feed_content.html", article=article),
                 content_type='html',
                 id=article.doi or article.pid,
                 author=article.authors,
                 url=url_external('main.article_detail_v3',
                                  url_seg=journal.url_segment,
                                  article_pid_v3=article.aid,
                                  lang=article_lang),
                 updated=journal.updated,
                 published=journal.created)

    return feed.get_response()


@main.route("/journal/<string:url_seg>/about/", methods=['GET'])
@cache.cached(key_prefix=cache_key_with_lang)
def about_journal(url_seg):
    language = session.get('lang', get_locale())

    journal = controllers.get_journal_by_url_seg(url_seg)

    if not journal:
        abort(404, _('Periódico não encontrado'))

    if not journal.is_public:
        abort(404, JOURNAL_UNPUBLISH + _(journal.unpublish_reason))

    latest_issue = utils.fix_journal_last_issue(journal)

    if latest_issue:
        latest_issue_legend = descriptive_short_format(
            title=journal.title, short_title=journal.short_title,
            pubdate=str(latest_issue.year), volume=latest_issue.volume, number=latest_issue.number,
            suppl=latest_issue.suppl_text, language=language[:2].lower())
    else:
        latest_issue_legend = None

    page = controllers.get_page_by_journal_acron_lang(journal.acronym, language)

    context = {
        'journal': journal,
        'latest_issue_legend': latest_issue_legend,
        'last_issue': latest_issue,
        'journal_study_areas': [
            STUDY_AREAS.get(study_area.upper()) for study_area in journal.study_areas
        ],
    }

    if page:
        context['content'] = page.content
        if page.updated_at:
            context['page_updated_at'] = page.updated_at

    return render_template("journal/about.html", **context)


@main.route("/journals/search/alpha/ajax/", methods=['GET', ])
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def journals_search_alpha_ajax():

    if not request.is_xhr:
        abort(400, _('Requisição inválida. Deve ser por ajax'))

    query = request.args.get('query', '', type=str)
    query_filter = request.args.get('query_filter', '', type=str)
    page = request.args.get('page', 1, type=int)
    lang = get_lang_from_session()[:2].lower()

    response_data = controllers.get_alpha_list_from_paginated_journals(
                        title_query=query,
                        query_filter=query_filter,
                        page=page,
                        lang=lang)

    return jsonify(response_data)


@main.route("/journals/search/group/by/filter/ajax/", methods=['GET'])
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def journals_search_by_theme_ajax():

    if not request.is_xhr:
        abort(400, _('Requisição inválida. Deve ser por ajax'))

    query = request.args.get('query', '', type=str)
    query_filter = request.args.get('query_filter', '', type=str)
    filter = request.args.get('filter', 'areas', type=str)
    lang = get_lang_from_session()[:2].lower()

    if filter == 'areas':
        objects = controllers.get_journals_grouped_by('study_areas', query, query_filter=query_filter, lang=lang)
    elif filter == 'wos':
        objects = controllers.get_journals_grouped_by('subject_categories', query, query_filter=query_filter, lang=lang)
    elif filter == 'publisher':
        objects = controllers.get_journals_grouped_by('publisher_name', query, query_filter=query_filter, lang=lang)
    else:
        return jsonify({
            'error': 401,
            'message': _('Parámetro "filter" é inválido, deve ser "areas", "wos" ou "publisher".')
        })
    return jsonify(objects)


@main.route("/journals/download/<string:list_type>/<string:extension>/", methods=['GET', ])
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def download_journal_list(list_type, extension):
    if extension.lower() not in ['csv', 'xls']:
        abort(401, _('Parámetro "extension" é inválido, deve ser "csv" ou "xls".'))
    elif list_type.lower() not in ['alpha', 'areas', 'wos', 'publisher']:
        abort(401, _('Parámetro "list_type" é inválido, deve ser: "alpha", "areas", "wos" ou "publisher".'))
    else:
        if extension.lower() == 'xls':
            mimetype = 'application/vnd.ms-excel'
        else:
            mimetype = 'text/csv'
        query = request.args.get('query', '', type=str)
        data = controllers.get_journal_generator_for_csv(list_type=list_type,
                                                         title_query=query,
                                                         extension=extension.lower())
        timestamp = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
        filename = 'journals_%s_%s.%s' % (list_type, timestamp, extension)
        response = Response(data, mimetype=mimetype)
        response.headers['Content-Disposition'] = 'attachment; filename=%s' % filename
        return response


@main.route("/<string:url_seg>/contact", methods=['POST'])
def contact(url_seg):

    if not request.is_xhr:
        abort(403, _('Requisição inválida, deve ser ajax.'))

    if utils.is_recaptcha_valid(request):

        form = forms.ContactForm(request.form)

        journal = controllers.get_journal_by_url_seg(url_seg)

        if not journal.enable_contact:
            abort(403, _('Periódico não permite envio de email.'))

        recipients = journal.editor_email

        if form.validate():
            sent, message = controllers.send_email_contact(recipients,
                                                           form.data['name'],
                                                           form.data['your_email'],
                                                           form.data['message'])

            return jsonify({'sent': sent, 'message': str(message),
                            'fields': [key for key in form.data.keys()]})

        else:
            return jsonify({'sent': False, 'message': form.errors,
                            'fields': [key for key in form.data.keys()]})

    else:
        abort(400, _('Requisição inválida, captcha inválido.'))


@main.route("/form_contact/<string:url_seg>/", methods=['GET'])
def form_contact(url_seg):
    journal = controllers.get_journal_by_url_seg(url_seg)
    if not journal:
        abort(404, _('Periódico não encontrado'))

    context = {
        'journal': journal
    }
    return render_template("journal/includes/contact_form.html", **context)


# ###################################Issue#######################################


@main.route('/grid/<string:url_seg>/')
def issue_grid_legacy(url_seg):
    return redirect(url_for('main.issue_grid', url_seg=url_seg), 301)


@main.route('/j/<string:url_seg>/grid')
@cache.cached(key_prefix=cache_key_with_lang)
def issue_grid(url_seg):
    journal = controllers.get_journal_by_url_seg(url_seg)

    if not journal:
        abort(404, _('Periódico não encontrado'))

    if not journal.is_public:
        abort(404, JOURNAL_UNPUBLISH + _(journal.unpublish_reason))

    # idioma da sessão
    language = session.get('lang', get_locale())

    # A ordenação padrão da função ``get_issues_by_jid``: "-year", "-volume", "-order"
    issues_data = controllers.get_issues_for_grid_by_jid(journal.id, is_public=True)
    latest_issue = issues_data['last_issue']
    if latest_issue:
        latest_issue_legend = descriptive_short_format(
            title=journal.title, short_title=journal.short_title,
            pubdate=str(latest_issue.year), volume=latest_issue.volume, number=latest_issue.number,
            suppl=latest_issue.suppl_text, language=language[:2].lower())
    else:
        latest_issue_legend = None

    context = {
        'journal': journal,
        'last_issue': issues_data['last_issue'],
        'latest_issue_legend': latest_issue_legend,
        'volume_issue': issues_data['volume_issue'],
        'ahead': issues_data['ahead'],
        'result_dict': issues_data['ordered_for_grid'],
        'journal_study_areas': [
            STUDY_AREAS.get(study_area.upper()) for study_area in journal.study_areas
        ],
    }

    return render_template("issue/grid.html", **context)


@main.route('/toc/<string:url_seg>/<string:url_seg_issue>/')
def issue_toc_legacy(url_seg, url_seg_issue):
    if url_seg_issue and "ahead" in url_seg_issue:
        return redirect(url_for('main.aop_toc', url_seg=url_seg), code=301)

    return redirect(
        url_for('main.issue_toc',
                url_seg=url_seg,
                url_seg_issue=url_seg_issue),
        code=301)


@main.route('/j/<string:url_seg>/i/<string:url_seg_issue>/')
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def issue_toc(url_seg, url_seg_issue):
    section_filter = None
    goto = request.args.get("goto", None, type=str)
    if goto not in ("previous", "next"):
        goto = None

    if goto in (None, "next") and "ahead" in url_seg_issue:
        # redireciona para `aop_toc`
        return redirect(url_for('main.aop_toc', url_seg=url_seg), code=301)

    # idioma da sessão
    language = session.get('lang', get_locale())

    if current_app.config["FILTER_SECTION_ENABLE"]:
        # seção dos documentos, se selecionada
        section_filter = request.args.get('section', '', type=str).upper()

    # obtém o issue
    issue = controllers.get_issue_by_url_seg(url_seg, url_seg_issue)
    if not issue:
        abort(404, _('Número não encontrado'))
    if not issue.is_public:
        abort(404, ISSUE_UNPUBLISH + _(issue.unpublish_reason))

    # obtém o journal
    journal = issue.journal
    if not journal.is_public:
        abort(404, JOURNAL_UNPUBLISH + _(journal.unpublish_reason))

    # completa url_segment do last_issue
    utils.fix_journal_last_issue(journal)

    # goto_next_or_previous_issue (redireciona)
    goto_url = goto_next_or_previous_issue(
        issue, request.args.get('goto', None, type=str))
    if goto_url:
        return redirect(goto_url, code=301)

    # obtém os documentos
    articles = controllers.get_articles_by_iid(issue.iid, is_public=True)
    if articles:
        # obtém TODAS as seções dos documentos deste sumário
        sections = sorted({a.section.upper() for a in articles if a.section})
    else:
        # obtém as seções dos documentos deste sumário
        sections = []

    if current_app.config["FILTER_SECTION_ENABLE"] and section_filter != '':
        # obtém somente os documentos da seção selecionada
        articles = [a for a in articles if a.section.upper() == section_filter]

    # obtém PDF e TEXT de cada documento
    has_math_content = False
    for article in articles:
        article_text_languages = [doc['lang'] for doc in article.htmls]
        article_pdf_languages = [(doc['lang'], doc['url']) for doc in article.pdfs]
        setattr(article, "article_text_languages", article_text_languages)
        setattr(article, "article_pdf_languages", article_pdf_languages)
        if 'mml:' in article.title:
            has_math_content = True

    # obtém a legenda bibliográfica
    issue_bibliographic_strip = descriptive_short_format(
        title=journal.title, short_title=journal.short_title,
        pubdate=str(issue.year), volume=issue.volume, number=issue.number,
        suppl=issue.suppl_text, language=language[:2].lower())

    context = {
        'this_page_url': url_for(
                            'main.issue_toc',
                            url_seg=url_seg,
                            url_seg_issue=url_seg_issue),
        'has_math_content': has_math_content,
        'journal': journal,
        'issue': issue,
        'issue_bibliographic_strip': issue_bibliographic_strip,
        'articles': articles,
        'sections': sections,
        'section_filter': section_filter,
        'journal_study_areas': [
            STUDY_AREAS.get(study_area.upper()) for study_area in journal.study_areas
        ],
        'last_issue': journal.last_issue
    }
    return render_template("issue/toc.html", **context)


def goto_next_or_previous_issue(current_issue, goto_param):
    if goto_param not in ["next", "previous"]:
        return None

    all_issues = list(
        controllers.get_issues_by_jid(current_issue.journal.id, is_public=True))
    if goto_param == "next":
        selected_issue = utils.get_next_issue(all_issues, current_issue)
    elif goto_param == "previous":
        selected_issue = utils.get_prev_issue(all_issues, current_issue)
    if selected_issue in (None, current_issue):
        # nao precisa redirecionar
        return None
    try:
        url_seg_issue = selected_issue.url_segment
    except AttributeError:
        return None
    else:
        return url_for('main.issue_toc',
                       url_seg=selected_issue.journal.url_segment,
                       url_seg_issue=url_seg_issue)


def get_next_or_previous_issue(current_issue, goto_param):
    if goto_param not in ["next", "previous"]:
        return current_issue

    all_issues = list(
        controllers.get_issues_by_jid(current_issue.journal.id, is_public=True))
    if goto_param == "next":
        return utils.get_next_issue(all_issues, current_issue)
    return utils.get_prev_issue(all_issues, current_issue)


@main.route('/j/<string:url_seg>/aop')
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def aop_toc(url_seg):

    section_filter = request.args.get('section', '', type=str).upper()

    aop_issues = controllers.get_aop_issues(url_seg) or []
    if not aop_issues:
        abort(404, _('Artigos ahead of print não encontrados'))

    goto = request.args.get("goto", None, type=str)
    if goto == "previous":
        url = goto_next_or_previous_issue(aop_issues[-1], goto)
        if url:
            redirect(url, code=301)

    journal = aop_issues[0].journal
    if not journal.is_public:
        abort(404, JOURNAL_UNPUBLISH + _(journal.unpublish_reason))

    utils.fix_journal_last_issue(journal)

    articles = []
    for aop_issue in aop_issues:
        _articles = controllers.get_articles_by_iid(
            aop_issue.iid, is_public=True)
        if _articles:
            articles.extend(_articles)
    if not articles:
        abort(404, _('Artigos ahead of print não encontrados'))

    sections = sorted({a.section.upper() for a in articles if a.section})
    if section_filter != '':
        articles = [a for a in articles if a.section.upper() == section_filter]

    for article in articles:
        article_text_languages = [doc['lang'] for doc in article.htmls]
        article_pdf_languages = [(doc['lang'], doc['url']) for doc in article.pdfs]

        setattr(article, "article_text_languages", article_text_languages)
        setattr(article, "article_pdf_languages", article_pdf_languages)

    context = {
        'this_page_url': url_for("main.aop_toc", url_seg=url_seg),
        'journal': journal,
        'issue': aop_issues[0],
        'issue_bibliographic_strip': "ahead of print",
        'articles': articles,
        'sections': sections,
        'section_filter': section_filter,
        'journal_study_areas': [
            STUDY_AREAS.get(study_area.upper())
            for study_area in journal.study_areas
        ],
        # o primeiro item da lista é o último número.
        'last_issue': journal.last_issue
    }

    return render_template("issue/toc.html", **context)


@main.route('/feed/<string:url_seg>/<string:url_seg_issue>/')
@cache.cached(key_prefix=cache_key_with_lang)
def issue_feed(url_seg, url_seg_issue):
    issue = controllers.get_issue_by_url_seg(url_seg, url_seg_issue)

    if not issue:
        abort(404, _('Número não encontrado'))

    if not issue.is_public:
        abort(404, ISSUE_UNPUBLISH + _(issue.unpublish_reason))

    if not issue.journal.is_public:
        abort(404, JOURNAL_UNPUBLISH + _(issue.journal.unpublish_reason))

    journal = issue.journal
    articles = controllers.get_articles_by_iid(issue.iid, is_public=True)

    feed = AtomFeed(journal.title or "",
                    feed_url=request.url,
                    url=request.url_root,
                    subtitle=utils.get_label_issue(issue))

    feed_language = session.get('lang', get_locale())

    for article in articles:
        # ######### TODO: Revisar #########
        article_lang = feed_language
        if feed_language not in article.languages:
            article_lang = article.original_language

        feed.add(article.title or 'Unknow title',
                 render_template("issue/feed_content.html", article=article),
                 content_type='html',
                 author=article.authors,
                 id=article.doi or article.pid,
                 url=url_external('main.article_detail_v3',
                                  url_seg=journal.url_segment,
                                  article_pid_v3=article.aid,
                                  lang=article_lang),
                 updated=journal.updated,
                 published=journal.created)

    return feed.get_response()

# ##################################Article######################################


@main.route('/article/<regex("S\d{4}-\d{3}[0-9xX][0-2][0-9]{3}\d{4}\d{5}"):pid>/')
@cache.cached(key_prefix=cache_key_with_lang)
def article_detail_pid(pid):

    article = controllers.get_article_by_pid(pid)

    if not article:
        article = controllers.get_article_by_oap_pid(pid)

    if not article:
        abort(404, _('Artigo não encontrado'))

    return redirect(url_for('main.article_detail_v3',
                            url_seg=article.journal.acronym,
                            article_pid_v3=article.aid))


def render_html_from_xml(article, lang, gs_abstract=False):
    logger.debug("Get XML: %s", article.xml)

    if current_app.config["SSM_XML_URL_REWRITE"]:
        result = fetch_data(use_ssm_url(article.xml))
    else:
        result = fetch_data(article.xml)

    xml = etree.parse(BytesIO(result))

    generator = HTMLGenerator.parse(
        xml, valid_only=False, gs_abstract=gs_abstract, output_style="website")

    return generator.generate(lang), generator.languages


def render_html_from_html(article, lang):
    html_url = [html
                for html in article.htmls
                if html['lang'] == lang]

    try:
        html_url = html_url[0]['url']
    except IndexError:
        raise ValueError('Artigo não encontrado') from None

    result = fetch_data(use_ssm_url(html_url))

    html = result.decode('utf8')

    text_languages = [html['lang'] for html in article.htmls]

    return html, text_languages


def render_html_abstract(article, lang):
    abstract_text = ''
    for abstract in article.abstracts:
        if abstract['language'] == lang:
            abstract_text = abstract["text"]
            break
    return abstract_text, article.abstract_languages


def render_html(article, lang, gs_abstract=False):
    if article.xml:
        return render_html_from_xml(article, lang, gs_abstract)
    elif article.htmls:
        if gs_abstract:
            return render_html_abstract(article, lang)
        return render_html_from_html(article, lang)
    else:
        # TODO: Corrigir os teste que esperam ter o atributo ``htmls``
        # O ideal seria levantar um ValueError.
        return '', []


# TODO: Remover assim que o valor Article.xml estiver consistente na base de
# dados
def use_ssm_url(url):
    """Normaliza a string `url` de acordo com os valores das diretivas de
    configuração OPAC_SSM_SCHEME, OPAC_SSM_DOMAIN e OPAC_SSM_PORT.

    A normalização busca obter uma URL absoluta em função de uma relativa, ou
    uma absoluta em função de uma absoluta, mas com as partes *scheme* e
    *authority* trocadas pelas definidas nas diretivas citadas anteriormente.

    Este código deve ser removido assim que o valor de Article.xml estiver
    consistente, i.e., todos os registros possuirem apenas URLs absolutas.
    """
    if url.startswith("http"):
        parsed_url = urlparse(url)
        return current_app.config["SSM_BASE_URI"] + parsed_url.path
    else:
        return current_app.config["SSM_BASE_URI"] + url


@main.route('/article/<string:url_seg>/<string:url_seg_issue>/<string:url_seg_article>/')
@main.route('/article/<string:url_seg>/<string:url_seg_issue>/<string:url_seg_article>/<regex("(?:\w{2})"):lang_code>/')
@main.route('/article/<string:url_seg>/<string:url_seg_issue>/<regex("(.*)"):url_seg_article>/')
@main.route('/article/<string:url_seg>/<string:url_seg_issue>/<regex("(.*)"):url_seg_article>/<regex("(?:\w{2})"):lang_code>/')
@cache.cached(key_prefix=cache_key_with_lang)
def article_detail(url_seg, url_seg_issue, url_seg_article, lang_code=''):
    issue = controllers.get_issue_by_url_seg(url_seg, url_seg_issue)
    if not issue:
        abort(404, _('Issue não encontrado'))

    article = controllers.get_article_by_issue_article_seg(issue.iid, url_seg_article)
    if article is None:
        article = controllers.get_article_by_aop_url_segs(
            issue.journal, url_seg_issue, url_seg_article
        )
    if article is None:
        abort(404, _('Artigo não encontrado'))

    req_params = {
            "url_seg": article.journal.acronym,
            "article_pid_v3": article.aid,
    }
    if lang_code:
        req_params["lang"] = lang_code

    return redirect(url_for('main.article_detail_v3', **req_params))


@main.route('/j/<string:url_seg>/a/<string:article_pid_v3>/')
@main.route('/j/<string:url_seg>/a/<string:article_pid_v3>/<string:part>/')
@cache.cached(key_prefix=cache_key_with_lang)
def article_detail_v3(url_seg, article_pid_v3, part=None):
    qs_lang = request.args.get('lang', type=str) or None
    qs_goto = request.args.get('goto', type=str) or None
    qs_stop = request.args.get('stop', type=str) or None
    qs_format = request.args.get('format', 'html', type=str)


    gs_abstract = (part == "abstract")
    if part and not gs_abstract:
        abort(404,
              _("Não existe '{}'. No seu lugar use '{}'"
                ).format(part, 'abstract'))

    try:
        qs_lang, article = controllers.get_article(
            article_pid_v3, url_seg, qs_lang, gs_abstract, qs_goto)
        if qs_goto:
            return redirect(
                url_for(
                    'main.article_detail_v3',
                    url_seg=url_seg,
                    article_pid_v3=article.aid,
                    part=part,
                    format=qs_format,
                    lang=qs_lang,
                    stop=getattr(article, 'stop', None),
                ),
                code=301
            )
    except (controllers.PreviousOrNextArticleNotFoundError) as e:
        if gs_abstract:
            abort(404, _('Resumo inexistente'))
        abort(404, _('Artigo inexistente'))
    except (controllers.ArticleNotFoundError,
            controllers.ArticleJournalNotFoundError):
        abort(404, _('Artigo não encontrado'))
    except controllers.ArticleLangNotFoundError:
        return redirect(
            url_for(
                'main.article_detail_v3',
                url_seg=url_seg,
                article_pid_v3=article_pid_v3,
                format=qs_format,
            ),
            code=301
        )
    except controllers.ArticleAbstractNotFoundError:
        abort(404, _('Recurso não encontrado'))
    except controllers.ArticleIsNotPublishedError as e:
        abort(404, "{}{}".format(ARTICLE_UNPUBLISH, e))
    except controllers.IssueIsNotPublishedError as e:
        abort(404, "{}{}".format(ISSUE_UNPUBLISH, e))
    except controllers.JournalIsNotPublishedError as e:
        abort(404, "{}{}".format(JOURNAL_UNPUBLISH, e))
    except ValueError as e:
        abort(404, str(e))

    def _handle_html():

        citation_pdf_url = None
        for pdf_data in article.pdfs:
            if pdf_data.get("lang") == qs_lang:
                citation_pdf_url = url_for(
                          'main.article_detail_v3',
                          url_seg=article.journal.url_segment,
                          article_pid_v3=article_pid_v3,
                          lang=qs_lang,
                          format="pdf",
                       )
                break

        website = request.url
        if website:
            parsed_url = urlparse(request.url)
            if current_app.config["FORCE_USE_HTTPS_GOOGLE_TAGS"]:
                website = "{}://{}".format('https', parsed_url.netloc)
            else:
                website = "{}://{}".format(parsed_url.scheme, parsed_url.netloc)
        if citation_pdf_url:
            citation_pdf_url = "{}{}".format(website, citation_pdf_url)
        try:
            html, text_languages = render_html(article, qs_lang, gs_abstract)
        except (ValueError, NonRetryableError):
            abort(404, _('HTML do Artigo não encontrado ou indisponível'))
        except RetryableError:
            abort(500, _('Erro inesperado'))

        text_versions = sorted(
               [
                   (
                       lang,
                       display_original_lang_name(lang),
                       url_for(
                          'main.article_detail_v3',
                          url_seg=article.journal.url_segment,
                          article_pid_v3=article_pid_v3,
                          lang=lang
                       )
                   )
                   for lang in text_languages
               ]
           )
        citation_xml_url = "{}{}".format(
            website,
            url_for(
                'main.article_detail_v3',
                url_seg=article.journal.url_segment,
                article_pid_v3=article_pid_v3,
                format="xml",
                lang=article.original_language,
            )
        )
        context = {
            'next_article': qs_stop != 'next',
            'previous_article': qs_stop != 'previous',
            'article': article,
            'journal': article.journal,
            'issue': article.issue,
            'html': html,
            'citation_pdf_url': citation_pdf_url,
            'citation_xml_url': citation_xml_url,
            'article_lang': qs_lang,
            'text_versions': text_versions,
            'related_links': controllers.related_links(article),
            'gs_abstract': gs_abstract,
            'part': part,
        }
        return render_template("article/detail.html", **context)

    def _handle_pdf():
        if not article.pdfs:
            abort(404, _('PDF do Artigo não encontrado'))

        pdf_info = [pdf for pdf in article.pdfs if pdf['lang'] == qs_lang]
        if len(pdf_info) != 1:
            abort(404, _('PDF do Artigo não encontrado'))

        try:
            pdf_url = pdf_info[0]['url']
        except (IndexError, KeyError, ValueError, TypeError):
            abort(404, _('PDF do Artigo não encontrado'))

        if pdf_url:
            return get_pdf_content(pdf_url)
        raise abort(404, _('Recurso do Artigo não encontrado. Caminho inválido!'))

    def _handle_xml():
        if current_app.config["SSM_XML_URL_REWRITE"]:
            result = fetch_data(use_ssm_url(article.xml))
        else:
            result = fetch_data(article.xml)
        response = make_response(result)
        response.headers['Content-Type'] = 'application/xml'
        return response

    if 'html' == qs_format:
        return _handle_html()
    elif 'pdf' == qs_format:
        return _handle_pdf()
    elif 'xml' == qs_format:
        return _handle_xml()
    else:
        abort(400, _('Formato não suportado'))


@main.route('/readcube/epdf/')
@main.route('/readcube/epdf.php')
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def article_epdf():
    doi = request.args.get('doi', None, type=str)
    pid = request.args.get('pid', None, type=str)
    pdf_path = request.args.get('pdf_path', None, type=str)
    lang = request.args.get('lang', None, type=str)

    if not all([doi, pid, pdf_path, lang]):
        abort(400, _('Parâmetros insuficientes para obter o EPDF do artigo'))
    else:
        context = {
            'doi': doi,
            'pid': pid,
            'pdf_path': pdf_path,
            'lang': lang,
        }
        return render_template("article/epdf.html", **context)


def get_pdf_content(url):
    logger.debug("Get PDF: %s", url)
    if current_app.config["SSM_ARTICLE_ASSETS_OR_RENDITIONS_URL_REWRITE"]:
        url = use_ssm_url(url)
    try:
        response = fetch_data(url)
    except NonRetryableError:
        abort(404, _('PDF não encontrado'))
    except RetryableError:
        abort(500, _('Erro inesperado'))
    else:
        mimetype, __ = mimetypes.guess_type(url)
        return Response(response, mimetype=mimetype)


@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def get_content_from_ssm(resource_ssm_media_path):
    resource_ssm_full_url = current_app.config['SSM_BASE_URI'] + resource_ssm_media_path

    url = resource_ssm_full_url.strip()
    mimetype, __ = mimetypes.guess_type(url)

    try:
        ssm_response = fetch_data(url)
    except NonRetryableError:
        abort(404, _('Recurso não encontrado'))
    except RetryableError:
        abort(500, _('Erro inesperado'))
    else:
        return Response(ssm_response, mimetype=mimetype)


@main.route('/media/assets/<regex("(.*)"):relative_media_path>')
@cache.cached(key_prefix=cache_key_with_lang)
def media_assets_proxy(relative_media_path):
    resource_ssm_path = '{ssm_media_path}{resource_path}'.format(
        ssm_media_path=current_app.config['SSM_MEDIA_PATH'],
        resource_path=relative_media_path)
    return get_content_from_ssm(resource_ssm_path)


@main.route('/article/ssm/content/raw/')
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def article_ssm_content_raw():
    resource_ssm_path = request.args.get('resource_ssm_path', None)
    if not resource_ssm_path:
        raise abort(404, _('Recurso do Artigo não encontrado. Caminho inválido!'))
    else:
        return get_content_from_ssm(resource_ssm_path)


@main.route('/pdf/<string:url_seg>/<string:url_seg_issue>/<string:url_seg_article>')
@main.route('/pdf/<string:url_seg>/<string:url_seg_issue>/<string:url_seg_article>/<regex("(?:\w{2})"):lang_code>')
@main.route('/pdf/<string:url_seg>/<string:url_seg_issue>/<regex("(.*)"):url_seg_article>')
@main.route('/pdf/<string:url_seg>/<string:url_seg_issue>/<regex("(.*)"):url_seg_article>/<regex("(?:\w{2})"):lang_code>')
@cache.cached(key_prefix=cache_key_with_lang)
def article_detail_pdf(url_seg, url_seg_issue, url_seg_article, lang_code=''):
    """
    Padrões esperados:
        `/pdf/csc/2021.v26suppl1/2557-2558`
        `/pdf/csc/2021.v26suppl1/2557-2558/en`
    """
    if not lang_code and "." not in url_seg_issue:
        return router_legacy_pdf(url_seg, url_seg_issue, url_seg_article)

    issue = controllers.get_issue_by_url_seg(url_seg, url_seg_issue)
    if not issue:
        abort(404, _('Issue não encontrado'))

    article = controllers.get_article_by_issue_article_seg(issue.iid, url_seg_article)
    if not article:
        abort(404, _('Artigo não encontrado'))

    req_params = {
        'url_seg': article.journal.url_segment,
        'article_pid_v3': article.aid,
        'format': 'pdf',
    }
    if lang_code:
        req_params['lang'] = lang_code

    return redirect(url_for('main.article_detail_v3', **req_params), code=301)


@main.route('/pdf/<string:journal_acron>/<string:issue_info>/<string:pdf_filename>.pdf')
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def router_legacy_pdf(journal_acron, issue_info, pdf_filename):
    pdf_filename = '%s.pdf' % pdf_filename

    journal = controllers.get_journal_by_url_seg(journal_acron)

    if not journal:
        abort(404, _('Este PDF não existe em http://www.scielo.br. Consulte http://search.scielo.org'))

    article = controllers.get_article_by_pdf_filename(
        journal_acron, issue_info, pdf_filename)

    if not article:
        abort(404, _('PDF do artigo não foi encontrado'))

    return redirect(
        url_for(
            'main.article_detail_v3',
            url_seg=article.journal.url_segment,
            article_pid_v3=article.aid,
            format='pdf',
            lang=article._pdf_lang,
        ),
        code=301
    )

@main.route('/cgi-bin/fbpe/<string:text_or_abstract>/')
@cache.cached(key_prefix=cache_key_with_lang_with_qs)
def router_legacy_article(text_or_abstract):
    pid = request.args.get('pid', None)
    lng = request.args.get('lng', None)
    if not (text_or_abstract in ['fbtext', 'fbabs'] and pid):
        # se tem pid
        abort(400, _('Requsição inválida ao tentar acessar o artigo com pid: %s' % pid))

    article = controllers.get_article_by_pid_v1(pid)
    if not article:
        abort(404, _('Artigo não encontrado'))

    return redirect(
        url_for(
            'main.article_detail_v3',
            url_seg=article.journal.url_segment,
            article_pid_v3=article.aid,
        ),
        code=301
    )


# ###############################E-mail share##################################


@main.route("/email_share_ajax/", methods=['POST'])
def email_share_ajax():

    if not request.is_xhr:
        abort(400, _('Requisição inválida.'))

    form = forms.EmailShareForm(request.form)

    if form.validate():
        recipients = [email.strip() for email in form.data['recipients'].split(';') if email.strip() != '']

        sent, message = controllers.send_email_share(form.data['your_email'],
                                                     recipients,
                                                     form.data['share_url'],
                                                     form.data['subject'],
                                                     form.data['comment'])

        return jsonify({'sent': sent, 'message': str(message),
                        'fields': [key for key in form.data.keys()]})

    else:
        return jsonify({'sent': False, 'message': form.errors,
                        'fields': [key for key in form.data.keys()]})


@main.route("/form_mail/", methods=['GET'])
def email_form():
    context = {'url': request.args.get('url')}
    return render_template("email/email_form.html", **context)


@main.route("/email_error_ajax/", methods=['POST'])
def email_error_ajax():

    if not request.is_xhr:
        abort(400, _('Requisição inválida.'))

    form = forms.ErrorForm(request.form)

    if form.validate():

        recipients = [email.strip() for email in current_app.config.get('EMAIL_ACCOUNTS_RECEIVE_ERRORS') if email.strip() != '']

        sent, message = controllers.send_email_error(form.data['name'],
                                                     form.data['your_email'],
                                                     recipients,
                                                     form.data['url'],
                                                     form.data['error_type'],
                                                     form.data['message'],
                                                     form.data['page_title'])

        return jsonify({'sent': sent, 'message': str(message),
                        'fields': [key for key in form.data.keys()]})

    else:
        return jsonify({'sent': False, 'message': form.errors,
                        'fields': [key for key in form.data.keys()]})


@main.route("/error_mail/", methods=['GET'])
def error_form():
    context = {'url': request.args.get('url')}
    return render_template("includes/error_form.html", **context)


# ###############################Others########################################


@main.route("/media/<path:filename>/", methods=['GET'])
@cache.cached(key_prefix=cache_key_with_lang)
def download_file_by_filename(filename):
    media_root = current_app.config['MEDIA_ROOT']
    return send_from_directory(media_root, filename)


@main.route("/img/scielo.gif", methods=['GET'])
def full_text_image():
    return send_from_directory('static', 'img/full_text_scielo_img.gif')


@main.route("/robots.txt", methods=['GET'])
def get_robots_txt_file():
    return send_from_directory('static', 'robots.txt')


@main.route("/revistas/<path:journal_seg>/<string:page>.htm", methods=['GET'])
def router_legacy_info_pages(journal_seg, page):
    """
    Essa view function realiza o redirecionamento das URLs antigas para as novas URLs.

    Mantém um dicionário como uma tabela relacionamento entre o nome das páginas que pode ser:

       Página      âncora

    [iaboutj.htm, eaboutj.htm, paboutj.htm] -> #about
    [iedboard.htm, eedboard.htm, pedboard.htm] -> #editors
    [iinstruc.htm einstruc.htm, pinstruc.htm]-> #instructions
    isubscrp.htm -> Sem âncora
    """

    page_anchor = {
        'iaboutj': '#about',
        'eaboutj': '#about',
        'paboutj': '#about',
        'eedboard': '#editors',
        'iedboard': '#editors',
        'pedboard': '#editors',
        'iinstruc': '#instructions',
        'pinstruc': '#instructions',
        'einstruc': '#instructions'
        }
    return redirect('%s%s' % (url_for('main.about_journal',
                                      url_seg=journal_seg), page_anchor.get(page, '')), code=301)


@main.route("/api/v1/counter_dict", methods=['GET'])
def router_counter_dicts():
    """
    Essa view function retorna um dicionário, em formato JSON, que mapeia PIDs a insumos
    necessários para o funcionamento das aplicações Matomo & COUNTER & SUSHI.
    """
    end_date = request.args.get('end_date', '', type=str)
    try:
        end_date = datetime.strptime(end_date, '%Y-%m-%d')
    except ValueError:
        end_date = datetime.now()
    begin_date = end_date - timedelta(days=30)

    page = request.args.get('page', type=int)
    if not page:
        page = 1

    limit = request.args.get('limit', type=int)
    if not limit or limit > 100 or limit < 0:
        limit = 100

    results = {'dictionary_date': end_date,
               'end_date': end_date.strftime('%Y-%m-%d %H-%M-%S'),
               'begin_date': begin_date.strftime('%Y-%m-%d %H-%M-%S'),
               'documents': {},
               'collection': current_app.config['OPAC_COLLECTION']}

    articles = controllers.get_articles_by_date_range(begin_date, end_date, page, limit)
    for a in articles.items:
        results['documents'].update(get_article_counter_data(a))

    results['total'] = articles.total
    results['pages'] = articles.pages
    results['limit'] = articles.per_page
    results['page'] = articles.page

    return jsonify(results)


def get_article_counter_data(article):
    return {
        article.aid: {
            "journal_acronym": article.journal.acronym,
            "pid": article.pid if article.pid else '',
            "aop_pid": article.aop_pid if article.aop_pid else '',
            "pid_v1": article.scielo_pids.get('v1', ''),
            "pid_v2": article.scielo_pids.get('v2', ''),
            "pid_v3": article.scielo_pids.get('v3', ''),
            "publication_date": article.publication_date,
            "default_language": article.original_language,
            "create": article.created,
            "update": article.updated
        }
    }


@main.route('/cgi-bin/wxis.exe/iah/')
def author_production():
    # http://www.scielo.br/cgi-bin/wxis.exe/iah/
    # ?IsisScript=iah/iah.xis&base=article%5Edlibrary&format=iso.pft&
    # lang=p&nextAction=lnk&
    # indexSearch=AU&exprSearch=MEIERHOFFER,+LILIAN+KOZSLOWSKI
    # ->
    # //search.scielo.org/?lang=pt&q=au:MEIERHOFFER,+LILIAN+KOZSLOWSKI

    search_url = current_app.config.get('URL_SEARCH')
    if not search_url:
        abort(404, "URL_SEARCH: {}".format(_('Página não encontrada')))

    qs_exprSearch = request.args.get('exprSearch', type=str) or ''
    qs_indexSearch = request.args.get('indexSearch', type=str) or ''
    qs_lang = request.args.get('lang', type=str) or ''

    _lang = IAHX_LANGS.get(qs_lang) or ''
    _lang = _lang and "lang={}".format(_lang)

    _expr = "{}{}".format(
        qs_indexSearch == "AU" and "au:" or '', qs_exprSearch)
    _expr = _expr and "q={}".format(_expr.replace(" ", "+"))

    _and = _lang and _expr and "&" or ''
    _question_mark = (_lang or _expr) and "?" or ""

    if search_url.startswith("//"):
        protocol = "https:"
    elif search_url.startswith("http"):
        protocol = ""
    else:
        protocol = "https://"

    url = "{}{}{}{}{}{}".format(
        protocol, search_url, _question_mark, _lang, _and, _expr)
    return redirect(url, code=301)

[((1059, 1086), 'logging.getLogger', 'logging.getLogger', (['__name__'], {}), '(__name__)\n', (1076, 1086), False, 'import logging\n'), ((1108, 1158), 'flask_babelex.gettext', '_', (['"""O periódico está indisponível por motivo de: """'], {}), "('O periódico está indisponível por motivo de: ')\n", (1109, 1158), True, 'from flask_babelex import gettext as _\n'), ((1177, 1224), 'flask_babelex.gettext', '_', (['"""O número está indisponível por motivo de: """'], {}), "('O número está indisponível por motivo de: ')\n", (1178, 1224), True, 'from flask_babelex import gettext as _\n'), ((1245, 1292), 'flask_babelex.gettext', '_', (['"""O artigo está indisponível por motivo de: """'], {}), "('O artigo está indisponível por motivo de: ')\n", (1246, 1292), True, 'from flask_babelex import gettext as _\n'), ((4989, 5033), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (5001, 5033), False, 'from webapp import cache\n'), ((6539, 6583), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (6551, 6583), False, 'from webapp import cache\n'), ((7125, 7169), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (7137, 7169), False, 'from webapp import cache\n'), ((8201, 8245), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (8213, 8245), False, 'from webapp import cache\n'), ((10219, 10271), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (10231, 10271), False, 'from webapp import cache\n'), ((10940, 10992), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (10952, 10992), False, 'from webapp import cache\n'), ((14994, 15038), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (15006, 15038), False, 'from webapp import cache\n'), ((17256, 17300), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (17268, 17300), False, 'from webapp import cache\n'), ((18945, 18989), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (18957, 18989), False, 'from webapp import cache\n'), ((20336, 20388), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (20348, 20388), False, 'from webapp import cache\n'), ((21076, 21128), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (21088, 21128), False, 'from webapp import cache\n'), ((22214, 22266), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (22226, 22266), False, 'from webapp import cache\n'), ((25187, 25231), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (25199, 25231), False, 'from webapp import cache\n'), ((27079, 27131), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (27091, 27131), False, 'from webapp import cache\n'), ((31711, 31763), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (31723, 31763), False, 'from webapp import cache\n'), ((33858, 33902), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (33870, 33902), False, 'from webapp import cache\n'), ((35622, 35666), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (35634, 35666), False, 'from webapp import cache\n'), ((38986, 39030), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (38998, 39030), False, 'from webapp import cache\n'), ((39934, 39978), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (39946, 39978), False, 'from webapp import cache\n'), ((46053, 46105), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (46065, 46105), False, 'from webapp import cache\n'), ((47144, 47196), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (47156, 47196), False, 'from webapp import cache\n'), ((47753, 47797), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (47765, 47797), False, 'from webapp import cache\n'), ((48108, 48160), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (48120, 48160), False, 'from webapp import cache\n'), ((48857, 48901), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (48869, 48901), False, 'from webapp import cache\n'), ((49892, 49944), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (49904, 49944), False, 'from webapp import cache\n'), ((50746, 50798), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang_with_qs'}), '(key_prefix=cache_key_with_lang_with_qs)\n', (50758, 50798), False, 'from webapp import cache\n'), ((54118, 54162), 'webapp.cache.cached', 'cache.cached', ([], {'key_prefix': 'cache_key_with_lang'}), '(key_prefix=cache_key_with_lang)\n', (54130, 54162), False, 'from webapp import cache\n'), ((1401, 1428), 'flask.url_for', 'url_for', (['endpoint'], {}), '(endpoint, **kwargs)\n', (1408, 1428), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((1440, 1470), 'urllib.parse.urljoin', 'urljoin', (['request.url_root', 'url'], {}), '(request.url_root, url)\n', (1447, 1470), False, 'from urllib.parse import urljoin\n'), ((3795, 3830), 'flask.current_app.config.get', 'current_app.config.get', (['"""LANGUAGES"""'], {}), "('LANGUAGES')\n", (3817, 3830), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((4367, 4402), 'flask.current_app.config.get', 'current_app.config.get', (['"""LANGUAGES"""'], {}), "('LANGUAGES')\n", (4389, 4402), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((4543, 4567), 'flask.request.args.get', 'request.args.get', (['"""hash"""'], {}), "('hash')\n", (4559, 4567), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((4691, 4709), 'flask.redirect', 'redirect', (['referrer'], {}), '(referrer)\n', (4699, 4709), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((5107, 5152), 'webapp.controllers.get_latest_news_by_lang', 'controllers.get_latest_news_by_lang', (['language'], {}), '(language)\n', (5142, 5152), False, 'from webapp import controllers\n'), ((5167, 5202), 'webapp.controllers.get_collection_tweets', 'controllers.get_collection_tweets', ([], {}), '()\n', (5200, 5202), False, 'from webapp import controllers\n'), ((5224, 5278), 'webapp.controllers.get_press_releases', 'controllers.get_press_releases', (["{'language': language}"], {}), "({'language': language})\n", (5254, 5278), False, 'from webapp import controllers\n'), ((6369, 6420), 'flask.render_template', 'render_template', (['"""collection/index.html"""'], {}), "('collection/index.html', **context)\n", (6384, 6420), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((6678, 6708), 'flask.request.args.get', 'request.args.get', (['"""status"""', '""""""'], {}), "('status', '')\n", (6694, 6708), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((6947, 7064), 'flask.render_template', 'render_template', (['"""collection/list_journal.html"""'], {}), "('collection/list_journal.html', **{'journals_list':\n    journals_list, 'query_filter': query_filter})\n", (6962, 7064), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((7477, 7507), 'flask.request.args.get', 'request.args.get', (['"""status"""', '""""""'], {}), "('status', '')\n", (7493, 7507), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((7526, 7555), 'flask.request.args.get', 'request.args.get', (['"""query"""', '""""""'], {}), "('query', '')\n", (7542, 7555), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((7578, 7613), 'flask.request.args.get', 'request.args.get', (['"""filter"""', '"""areas"""'], {}), "('filter', 'areas')\n", (7594, 7613), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((7844, 7967), 'webapp.controllers.get_journals_grouped_by', 'controllers.get_journals_grouped_by', (['thematic_table[thematic_filter]', 'title_query'], {'query_filter': 'query_filter', 'lang': 'lang'}), '(thematic_table[thematic_filter],\n    title_query, query_filter=query_filter, lang=lang)\n', (7879, 7967), False, 'from webapp import controllers\n'), ((8015, 8148), 'flask.render_template', 'render_template', (['"""collection/list_thematic.html"""'], {}), "('collection/list_thematic.html', **{'objects': objects,\n    'query_filter': query_filter, 'filter': thematic_filter})\n", (8030, 8148), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((8340, 8376), 'webapp.controllers.get_current_collection', 'controllers.get_current_collection', ([], {}), '()\n', (8374, 8376), False, 'from webapp import controllers\n'), ((8490, 8558), 'flask_babelex.gettext', '_', (["('10 últimos periódicos inseridos na coleção %s' % collection.name)"], {}), "('10 últimos periódicos inseridos na coleção %s' % collection.name)\n", (8491, 8558), True, 'from flask_babelex import gettext as _\n'), ((8571, 8649), 'werkzeug.contrib.atom.AtomFeed', 'AtomFeed', (['title'], {'subtitle': 'subtitle', 'feed_url': 'request.url', 'url': 'request.url_root'}), '(title, subtitle=subtitle, feed_url=request.url, url=request.url_root)\n', (8579, 8649), False, 'from werkzeug.contrib.atom import AtomFeed\n'), ((8706, 8803), 'webapp.controllers.get_journals_paginated', 'controllers.get_journals_paginated', ([], {'title_query': '""""""', 'page': '(1)', 'order_by': '"""-created"""', 'per_page': '(10)'}), "(title_query='', page=1, order_by=\n    '-created', per_page=10)\n", (8740, 8803), False, 'from webapp import controllers\n'), ((10773, 10824), 'flask.render_template', 'render_template', (['"""collection/about.html"""'], {}), "('collection/about.html', **context)\n", (10788, 10824), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((11032, 11064), 'flask.request.args.get', 'request.args.get', (['"""script"""', 'None'], {}), "('script', None)\n", (11048, 11064), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((11075, 11104), 'flask.request.args.get', 'request.args.get', (['"""pid"""', 'None'], {}), "('pid', None)\n", (11091, 11104), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((11116, 11146), 'flask.request.args.get', 'request.args.get', (['"""tlng"""', 'None'], {}), "('tlng', None)\n", (11132, 11146), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((15082, 15125), 'webapp.controllers.get_journal_by_url_seg', 'controllers.get_journal_by_url_seg', (['url_seg'], {}), '(url_seg)\n', (15116, 15125), False, 'from webapp import controllers\n'), ((15301, 15338), 'webapp.utils.utils.fix_journal_last_issue', 'utils.fix_journal_last_issue', (['journal'], {}), '(journal)\n', (15329, 15338), False, 'from webapp.utils import utils\n'), ((15472, 15517), 'webapp.controllers.get_latest_news_by_lang', 'controllers.get_latest_news_by_lang', (['language'], {}), '(language)\n', (15507, 15517), False, 'from webapp import controllers\n'), ((15561, 15635), 'webapp.controllers.get_press_releases', 'controllers.get_press_releases', (["{'journal': journal, 'language': language}"], {}), "({'journal': journal, 'language': language})\n", (15591, 15635), False, 'from webapp import controllers\n'), ((16517, 16557), 'webapp.controllers.get_journal_metrics', 'controllers.get_journal_metrics', (['journal'], {}), '(journal)\n', (16548, 16557), False, 'from webapp import controllers\n'), ((17156, 17205), 'flask.render_template', 'render_template', (['"""journal/detail.html"""'], {}), "('journal/detail.html', **context)\n", (17171, 17205), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((17342, 17385), 'webapp.controllers.get_journal_by_url_seg', 'controllers.get_journal_by_url_seg', (['url_seg'], {}), '(url_seg)\n', (17376, 17385), False, 'from webapp import controllers\n'), ((17570, 17628), 'webapp.controllers.get_issues_by_jid', 'controllers.get_issues_by_jid', (['journal.jid'], {'is_public': '(True)'}), '(journal.jid, is_public=True)\n', (17599, 17628), False, 'from webapp import controllers\n'), ((17691, 17754), 'webapp.controllers.get_articles_by_iid', 'controllers.get_articles_by_iid', (['last_issue.iid'], {'is_public': '(True)'}), '(last_issue.iid, is_public=True)\n', (17722, 17754), False, 'from webapp import controllers\n'), ((19082, 19125), 'webapp.controllers.get_journal_by_url_seg', 'controllers.get_journal_by_url_seg', (['url_seg'], {}), '(url_seg)\n', (19116, 19125), False, 'from webapp import controllers\n'), ((19316, 19353), 'webapp.utils.utils.fix_journal_last_issue', 'utils.fix_journal_last_issue', (['journal'], {}), '(journal)\n', (19344, 19353), False, 'from webapp.utils import utils\n'), ((19729, 19798), 'webapp.controllers.get_page_by_journal_acron_lang', 'controllers.get_page_by_journal_acron_lang', (['journal.acronym', 'language'], {}), '(journal.acronym, language)\n', (19771, 19798), False, 'from webapp import controllers\n'), ((20221, 20269), 'flask.render_template', 'render_template', (['"""journal/about.html"""'], {}), "('journal/about.html', **context)\n", (20236, 20269), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((20528, 20567), 'flask.request.args.get', 'request.args.get', (['"""query"""', '""""""'], {'type': 'str'}), "('query', '', type=str)\n", (20544, 20567), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((20587, 20633), 'flask.request.args.get', 'request.args.get', (['"""query_filter"""', '""""""'], {'type': 'str'}), "('query_filter', '', type=str)\n", (20603, 20633), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((20645, 20682), 'flask.request.args.get', 'request.args.get', (['"""page"""', '(1)'], {'type': 'int'}), "('page', 1, type=int)\n", (20661, 20682), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((20751, 20873), 'webapp.controllers.get_alpha_list_from_paginated_journals', 'controllers.get_alpha_list_from_paginated_journals', ([], {'title_query': 'query', 'query_filter': 'query_filter', 'page': 'page', 'lang': 'lang'}), '(title_query=query,\n    query_filter=query_filter, page=page, lang=lang)\n', (20801, 20873), False, 'from webapp import controllers\n'), ((20979, 21001), 'flask.jsonify', 'jsonify', (['response_data'], {}), '(response_data)\n', (20986, 21001), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((21271, 21310), 'flask.request.args.get', 'request.args.get', (['"""query"""', '""""""'], {'type': 'str'}), "('query', '', type=str)\n", (21287, 21310), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((21330, 21376), 'flask.request.args.get', 'request.args.get', (['"""query_filter"""', '""""""'], {'type': 'str'}), "('query_filter', '', type=str)\n", (21346, 21376), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((21390, 21435), 'flask.request.args.get', 'request.args.get', (['"""filter"""', '"""areas"""'], {'type': 'str'}), "('filter', 'areas', type=str)\n", (21406, 21435), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((22102, 22118), 'flask.jsonify', 'jsonify', (['objects'], {}), '(objects)\n', (22109, 22118), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((23558, 23591), 'webapp.utils.utils.is_recaptcha_valid', 'utils.is_recaptcha_valid', (['request'], {}), '(request)\n', (23582, 23591), False, 'from webapp.utils import utils\n'), ((24677, 24720), 'webapp.controllers.get_journal_by_url_seg', 'controllers.get_journal_by_url_seg', (['url_seg'], {}), '(url_seg)\n', (24711, 24720), False, 'from webapp import controllers\n'), ((24852, 24916), 'flask.render_template', 'render_template', (['"""journal/includes/contact_form.html"""'], {}), "('journal/includes/contact_form.html', **context)\n", (24867, 24916), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((25271, 25314), 'webapp.controllers.get_journal_by_url_seg', 'controllers.get_journal_by_url_seg', (['url_seg'], {}), '(url_seg)\n', (25305, 25314), False, 'from webapp import controllers\n'), ((25664, 25730), 'webapp.controllers.get_issues_for_grid_by_jid', 'controllers.get_issues_for_grid_by_jid', (['journal.id'], {'is_public': '(True)'}), '(journal.id, is_public=True)\n', (25702, 25730), False, 'from webapp import controllers\n'), ((26580, 26625), 'flask.render_template', 'render_template', (['"""issue/grid.html"""'], {}), "('issue/grid.html', **context)\n", (26595, 26625), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((27208, 27248), 'flask.request.args.get', 'request.args.get', (['"""goto"""', 'None'], {'type': 'str'}), "('goto', None, type=str)\n", (27224, 27248), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((27765, 27821), 'webapp.controllers.get_issue_by_url_seg', 'controllers.get_issue_by_url_seg', (['url_seg', 'url_seg_issue'], {}), '(url_seg, url_seg_issue)\n', (27797, 27821), False, 'from webapp import controllers\n'), ((28174, 28211), 'webapp.utils.utils.fix_journal_last_issue', 'utils.fix_journal_last_issue', (['journal'], {}), '(journal)\n', (28202, 28211), False, 'from webapp.utils import utils\n'), ((28465, 28523), 'webapp.controllers.get_articles_by_iid', 'controllers.get_articles_by_iid', (['issue.iid'], {'is_public': '(True)'}), '(issue.iid, is_public=True)\n', (28496, 28523), False, 'from webapp import controllers\n'), ((30407, 30451), 'flask.render_template', 'render_template', (['"""issue/toc.html"""'], {}), "('issue/toc.html', **context)\n", (30422, 30451), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((31621, 31668), 'webapp.utils.utils.get_prev_issue', 'utils.get_prev_issue', (['all_issues', 'current_issue'], {}), '(all_issues, current_issue)\n', (31641, 31668), False, 'from webapp.utils import utils\n'), ((32017, 32057), 'flask.request.args.get', 'request.args.get', (['"""goto"""', 'None'], {'type': 'str'}), "('goto', None, type=str)\n", (32033, 32057), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((32341, 32378), 'webapp.utils.utils.fix_journal_last_issue', 'utils.fix_journal_last_issue', (['journal'], {}), '(journal)\n', (32369, 32378), False, 'from webapp.utils import utils\n'), ((33748, 33792), 'flask.render_template', 'render_template', (['"""issue/toc.html"""'], {}), "('issue/toc.html', **context)\n", (33763, 33792), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((33955, 34011), 'webapp.controllers.get_issue_by_url_seg', 'controllers.get_issue_by_url_seg', (['url_seg', 'url_seg_issue'], {}), '(url_seg, url_seg_issue)\n', (33987, 34011), False, 'from webapp import controllers\n'), ((34326, 34384), 'webapp.controllers.get_articles_by_iid', 'controllers.get_articles_by_iid', (['issue.iid'], {'is_public': '(True)'}), '(issue.iid, is_public=True)\n', (34357, 34384), False, 'from webapp import controllers\n'), ((35711, 35746), 'webapp.controllers.get_article_by_pid', 'controllers.get_article_by_pid', (['pid'], {}), '(pid)\n', (35741, 35746), False, 'from webapp import controllers\n'), ((36387, 36482), 'packtools.HTMLGenerator.parse', 'HTMLGenerator.parse', (['xml'], {'valid_only': '(False)', 'gs_abstract': 'gs_abstract', 'output_style': '"""website"""'}), "(xml, valid_only=False, gs_abstract=gs_abstract,\n    output_style='website')\n", (36406, 36482), False, 'from packtools import HTMLGenerator\n'), ((39118, 39174), 'webapp.controllers.get_issue_by_url_seg', 'controllers.get_issue_by_url_seg', (['url_seg', 'url_seg_issue'], {}), '(url_seg, url_seg_issue)\n', (39150, 39174), False, 'from webapp import controllers\n'), ((39254, 39326), 'webapp.controllers.get_article_by_issue_article_seg', 'controllers.get_article_by_issue_article_seg', (['issue.iid', 'url_seg_article'], {}), '(issue.iid, url_seg_article)\n', (39298, 39326), False, 'from webapp import controllers\n'), ((40225, 40269), 'flask.request.args.get', 'request.args.get', (['"""format"""', '"""html"""'], {'type': 'str'}), "('format', 'html', type=str)\n", (40241, 40269), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((46136, 46175), 'flask.request.args.get', 'request.args.get', (['"""doi"""', 'None'], {'type': 'str'}), "('doi', None, type=str)\n", (46152, 46175), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((46186, 46225), 'flask.request.args.get', 'request.args.get', (['"""pid"""', 'None'], {'type': 'str'}), "('pid', None, type=str)\n", (46202, 46225), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((46241, 46285), 'flask.request.args.get', 'request.args.get', (['"""pdf_path"""', 'None'], {'type': 'str'}), "('pdf_path', None, type=str)\n", (46257, 46285), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((46297, 46337), 'flask.request.args.get', 'request.args.get', (['"""lang"""', 'None'], {'type': 'str'}), "('lang', None, type=str)\n", (46313, 46337), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((47397, 47422), 'mimetypes.guess_type', 'mimetypes.guess_type', (['url'], {}), '(url)\n', (47417, 47422), False, 'import mimetypes\n'), ((48216, 48259), 'flask.request.args.get', 'request.args.get', (['"""resource_ssm_path"""', 'None'], {}), "('resource_ssm_path', None)\n", (48232, 48259), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((49249, 49305), 'webapp.controllers.get_issue_by_url_seg', 'controllers.get_issue_by_url_seg', (['url_seg', 'url_seg_issue'], {}), '(url_seg, url_seg_issue)\n', (49281, 49305), False, 'from webapp import controllers\n'), ((49385, 49457), 'webapp.controllers.get_article_by_issue_article_seg', 'controllers.get_article_by_issue_article_seg', (['issue.iid', 'url_seg_article'], {}), '(issue.iid, url_seg_article)\n', (49429, 49457), False, 'from webapp import controllers\n'), ((50067, 50116), 'webapp.controllers.get_journal_by_url_seg', 'controllers.get_journal_by_url_seg', (['journal_acron'], {}), '(journal_acron)\n', (50101, 50116), False, 'from webapp import controllers\n'), ((50257, 50342), 'webapp.controllers.get_article_by_pdf_filename', 'controllers.get_article_by_pdf_filename', (['journal_acron', 'issue_info', 'pdf_filename'], {}), '(journal_acron, issue_info, pdf_filename\n    )\n', (50296, 50342), False, 'from webapp import controllers\n'), ((50854, 50883), 'flask.request.args.get', 'request.args.get', (['"""pid"""', 'None'], {}), "('pid', None)\n", (50870, 50883), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((50894, 50923), 'flask.request.args.get', 'request.args.get', (['"""lng"""', 'None'], {}), "('lng', None)\n", (50910, 50923), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((51111, 51149), 'webapp.controllers.get_article_by_pid_v1', 'controllers.get_article_by_pid_v1', (['pid'], {}), '(pid)\n', (51144, 51149), False, 'from webapp import controllers\n'), ((51663, 51697), 'webapp.forms.EmailShareForm', 'forms.EmailShareForm', (['request.form'], {}), '(request.form)\n', (51683, 51697), False, 'from webapp import forms\n'), ((52602, 52653), 'flask.render_template', 'render_template', (['"""email/email_form.html"""'], {}), "('email/email_form.html', **context)\n", (52617, 52653), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((52818, 52847), 'webapp.forms.ErrorForm', 'forms.ErrorForm', (['request.form'], {}), '(request.form)\n', (52833, 52847), False, 'from webapp import forms\n'), ((53922, 53976), 'flask.render_template', 'render_template', (['"""includes/error_form.html"""'], {}), "('includes/error_form.html', **context)\n", (53937, 53976), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((54265, 54306), 'flask.send_from_directory', 'send_from_directory', (['media_root', 'filename'], {}), '(media_root, filename)\n', (54284, 54306), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((54391, 54452), 'flask.send_from_directory', 'send_from_directory', (['"""static"""', '"""img/full_text_scielo_img.gif"""'], {}), "('static', 'img/full_text_scielo_img.gif')\n", (54410, 54452), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((54537, 54580), 'flask.send_from_directory', 'send_from_directory', (['"""static"""', '"""robots.txt"""'], {}), "('static', 'robots.txt')\n", (54556, 54580), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((55907, 55949), 'flask.request.args.get', 'request.args.get', (['"""end_date"""', '""""""'], {'type': 'str'}), "('end_date', '', type=str)\n", (55923, 55949), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((56134, 56168), 'flask.request.args.get', 'request.args.get', (['"""page"""'], {'type': 'int'}), "('page', type=int)\n", (56150, 56168), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((56216, 56251), 'flask.request.args.get', 'request.args.get', (['"""limit"""'], {'type': 'int'}), "('limit', type=int)\n", (56232, 56251), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((56617, 56690), 'webapp.controllers.get_articles_by_date_range', 'controllers.get_articles_by_date_range', (['begin_date', 'end_date', 'page', 'limit'], {}), '(begin_date, end_date, page, limit)\n', (56655, 56690), False, 'from webapp import controllers\n'), ((56951, 56967), 'flask.jsonify', 'jsonify', (['results'], {}), '(results)\n', (56958, 56967), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((57978, 58014), 'flask.current_app.config.get', 'current_app.config.get', (['"""URL_SEARCH"""'], {}), "('URL_SEARCH')\n", (58000, 58014), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((58915, 58938), 'flask.redirect', 'redirect', (['url'], {'code': '(301)'}), '(url, code=301)\n', (58923, 58938), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((1964, 1998), 'requests.get', 'requests.get', (['url'], {'timeout': 'timeout'}), '(url, timeout=timeout)\n', (1976, 1998), False, 'import requests\n'), ((3328, 3350), 'webapp.forms.EmailShareForm', 'forms.EmailShareForm', ([], {}), '()\n', (3348, 3350), False, 'from webapp import forms\n'), ((3384, 3403), 'webapp.forms.ContactForm', 'forms.ContactForm', ([], {}), '()\n', (3401, 3403), False, 'from webapp import forms\n'), ((3429, 3446), 'webapp.forms.ErrorForm', 'forms.ErrorForm', ([], {}), '()\n', (3444, 3446), False, 'from webapp import forms\n'), ((4204, 4250), 'flask.current_app.config.get', 'current_app.config.get', (['"""BABEL_DEFAULT_LOCALE"""'], {}), "('BABEL_DEFAULT_LOCALE')\n", (4226, 4250), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((6811, 6853), 'webapp.controllers.get_journal_json_data', 'controllers.get_journal_json_data', (['journal'], {}), '(journal)\n', (6844, 6853), False, 'from webapp import controllers\n'), ((9012, 9070), 'webapp.controllers.get_issues_by_jid', 'controllers.get_issues_by_jid', (['journal.jid'], {'is_public': '(True)'}), '(journal.jid, is_public=True)\n', (9041, 9070), False, 'from webapp import controllers\n'), ((9333, 9346), 'collections.OrderedDict', 'OrderedDict', ([], {}), '()\n', (9344, 9346), False, 'from collections import OrderedDict\n'), ((10457, 10511), 'webapp.controllers.get_page_by_slug_name', 'controllers.get_page_by_slug_name', (['slug_name', 'language'], {}), '(slug_name, language)\n', (10490, 10511), False, 'from webapp import controllers\n'), ((10688, 10727), 'webapp.controllers.get_pages_by_lang', 'controllers.get_pages_by_lang', (['language'], {}), '(language)\n', (10717, 10727), False, 'from webapp import controllers\n'), ((14864, 14915), 'flask.url_for', 'url_for', (['"""main.journal_detail"""'], {'url_seg': 'journal_seg'}), "('main.journal_detail', url_seg=journal_seg)\n", (14871, 14915), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((15952, 16037), 'webapp.controllers.get_recent_articles_of_issue', 'controllers.get_recent_articles_of_issue', (['journal.last_issue.iid'], {'is_public': '(True)'}), '(journal.last_issue.iid, is_public=True\n    )\n', (15992, 16037), False, 'from webapp import controllers\n'), ((21528, 21628), 'webapp.controllers.get_journals_grouped_by', 'controllers.get_journals_grouped_by', (['"""study_areas"""', 'query'], {'query_filter': 'query_filter', 'lang': 'lang'}), "('study_areas', query, query_filter=\n    query_filter, lang=lang)\n", (21563, 21628), False, 'from webapp import controllers\n'), ((23609, 23640), 'webapp.forms.ContactForm', 'forms.ContactForm', (['request.form'], {}), '(request.form)\n', (23626, 23640), False, 'from webapp import forms\n'), ((23660, 23703), 'webapp.controllers.get_journal_by_url_seg', 'controllers.get_journal_by_url_seg', (['url_seg'], {}), '(url_seg)\n', (23694, 23703), False, 'from webapp import controllers\n'), ((25094, 25137), 'flask.url_for', 'url_for', (['"""main.issue_grid"""'], {'url_seg': 'url_seg'}), "('main.issue_grid', url_seg=url_seg)\n", (25101, 25137), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((26892, 26963), 'flask.url_for', 'url_for', (['"""main.issue_toc"""'], {'url_seg': 'url_seg', 'url_seg_issue': 'url_seg_issue'}), "('main.issue_toc', url_seg=url_seg, url_seg_issue=url_seg_issue)\n", (26899, 26963), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((28320, 28360), 'flask.request.args.get', 'request.args.get', (['"""goto"""', 'None'], {'type': 'str'}), "('goto', None, type=str)\n", (28336, 28360), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((28394, 28422), 'flask.redirect', 'redirect', (['goto_url'], {'code': '(301)'}), '(goto_url, code=301)\n', (28402, 28422), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((29797, 29868), 'flask.url_for', 'url_for', (['"""main.issue_toc"""'], {'url_seg': 'url_seg', 'url_seg_issue': 'url_seg_issue'}), "('main.issue_toc', url_seg=url_seg, url_seg_issue=url_seg_issue)\n", (29804, 29868), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((30613, 30684), 'webapp.controllers.get_issues_by_jid', 'controllers.get_issues_by_jid', (['current_issue.journal.id'], {'is_public': '(True)'}), '(current_issue.journal.id, is_public=True)\n', (30642, 30684), False, 'from webapp import controllers\n'), ((30740, 30787), 'webapp.utils.utils.get_next_issue', 'utils.get_next_issue', (['all_issues', 'current_issue'], {}), '(all_issues, current_issue)\n', (30760, 30787), False, 'from webapp.utils import utils\n'), ((31131, 31233), 'flask.url_for', 'url_for', (['"""main.issue_toc"""'], {'url_seg': 'selected_issue.journal.url_segment', 'url_seg_issue': 'url_seg_issue'}), "('main.issue_toc', url_seg=selected_issue.journal.url_segment,\n    url_seg_issue=url_seg_issue)\n", (31138, 31233), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((31445, 31516), 'webapp.controllers.get_issues_by_jid', 'controllers.get_issues_by_jid', (['current_issue.journal.id'], {'is_public': '(True)'}), '(current_issue.journal.id, is_public=True)\n', (31474, 31516), False, 'from webapp import controllers\n'), ((31562, 31609), 'webapp.utils.utils.get_next_issue', 'utils.get_next_issue', (['all_issues', 'current_issue'], {}), '(all_issues, current_issue)\n', (31582, 31609), False, 'from webapp.utils import utils\n'), ((31876, 31911), 'webapp.controllers.get_aop_issues', 'controllers.get_aop_issues', (['url_seg'], {}), '(url_seg)\n', (31902, 31911), False, 'from webapp import controllers\n'), ((32451, 32513), 'webapp.controllers.get_articles_by_iid', 'controllers.get_articles_by_iid', (['aop_issue.iid'], {'is_public': '(True)'}), '(aop_issue.iid, is_public=True)\n', (32482, 32513), False, 'from webapp import controllers\n'), ((33234, 33274), 'flask.url_for', 'url_for', (['"""main.aop_toc"""'], {'url_seg': 'url_seg'}), "('main.aop_toc', url_seg=url_seg)\n", (33241, 33274), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((35786, 35825), 'webapp.controllers.get_article_by_oap_pid', 'controllers.get_article_by_oap_pid', (['pid'], {}), '(pid)\n', (35820, 35825), False, 'from webapp import controllers\n'), ((35915, 36013), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {'url_seg': 'article.journal.acronym', 'article_pid_v3': 'article.aid'}), "('main.article_detail_v3', url_seg=article.journal.acronym,\n    article_pid_v3=article.aid)\n", (35922, 36013), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((36353, 36368), 'io.BytesIO', 'BytesIO', (['result'], {}), '(result)\n', (36360, 36368), False, 'from io import BytesIO\n'), ((38399, 38412), 'urllib.parse.urlparse', 'urlparse', (['url'], {}), '(url)\n', (38407, 38412), False, 'from urllib.parse import urlparse\n'), ((39369, 39459), 'webapp.controllers.get_article_by_aop_url_segs', 'controllers.get_article_by_aop_url_segs', (['issue.journal', 'url_seg_issue', 'url_seg_article'], {}), '(issue.journal, url_seg_issue,\n    url_seg_article)\n', (39408, 39459), False, 'from webapp import controllers\n'), ((39744, 39791), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {}), "('main.article_detail_v3', **req_params)\n", (39751, 39791), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((40052, 40086), 'flask.request.args.get', 'request.args.get', (['"""lang"""'], {'type': 'str'}), "('lang', type=str)\n", (40068, 40086), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((40109, 40143), 'flask.request.args.get', 'request.args.get', (['"""goto"""'], {'type': 'str'}), "('goto', type=str)\n", (40125, 40143), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((40166, 40200), 'flask.request.args.get', 'request.args.get', (['"""stop"""'], {'type': 'str'}), "('stop', type=str)\n", (40182, 40200), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((40501, 40580), 'webapp.controllers.get_article', 'controllers.get_article', (['article_pid_v3', 'url_seg', 'qs_lang', 'gs_abstract', 'qs_goto'], {}), '(article_pid_v3, url_seg, qs_lang, gs_abstract, qs_goto)\n', (40524, 40580), False, 'from webapp import controllers\n'), ((44783, 44832), 'flask.render_template', 'render_template', (['"""article/detail.html"""'], {}), "('article/detail.html', **context)\n", (44798, 44832), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((45646, 45667), 'flask.make_response', 'make_response', (['result'], {}), '(result)\n', (45659, 45667), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((46624, 46671), 'flask.render_template', 'render_template', (['"""article/epdf.html"""'], {}), "('article/epdf.html', **context)\n", (46639, 46671), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((47062, 47087), 'mimetypes.guess_type', 'mimetypes.guess_type', (['url'], {}), '(url)\n', (47082, 47087), False, 'import mimetypes\n'), ((47103, 47140), 'flask.Response', 'Response', (['response'], {'mimetype': 'mimetype'}), '(response, mimetype=mimetype)\n', (47111, 47140), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((47643, 47684), 'flask.Response', 'Response', (['ssm_response'], {'mimetype': 'mimetype'}), '(ssm_response, mimetype=mimetype)\n', (47651, 47684), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((49741, 49788), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {}), "('main.article_detail_v3', **req_params)\n", (49748, 49788), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((50456, 50596), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {'url_seg': 'article.journal.url_segment', 'article_pid_v3': 'article.aid', 'format': '"""pdf"""', 'lang': 'article._pdf_lang'}), "('main.article_detail_v3', url_seg=article.journal.url_segment,\n    article_pid_v3=article.aid, format='pdf', lang=article._pdf_lang)\n", (50463, 50596), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((51247, 51349), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {'url_seg': 'article.journal.url_segment', 'article_pid_v3': 'article.aid'}), "('main.article_detail_v3', url_seg=article.journal.url_segment,\n    article_pid_v3=article.aid)\n", (51254, 51349), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((51856, 51994), 'webapp.controllers.send_email_share', 'controllers.send_email_share', (["form.data['your_email']", 'recipients', "form.data['share_url']", "form.data['subject']", "form.data['comment']"], {}), "(form.data['your_email'], recipients, form.data\n    ['share_url'], form.data['subject'], form.data['comment'])\n", (51884, 51994), False, 'from webapp import controllers\n'), ((52566, 52589), 'flask.request.args.get', 'request.args.get', (['"""url"""'], {}), "('url')\n", (52582, 52589), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((53028, 53211), 'webapp.controllers.send_email_error', 'controllers.send_email_error', (["form.data['name']", "form.data['your_email']", 'recipients', "form.data['url']", "form.data['error_type']", "form.data['message']", "form.data['page_title']"], {}), "(form.data['name'], form.data['your_email'],\n    recipients, form.data['url'], form.data['error_type'], form.data[\n    'message'], form.data['page_title'])\n", (53056, 53211), False, 'from webapp import controllers\n'), ((53886, 53909), 'flask.request.args.get', 'request.args.get', (['"""url"""'], {}), "('url')\n", (53902, 53909), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((55978, 56017), 'datetime.datetime.strptime', 'datetime.strptime', (['end_date', '"""%Y-%m-%d"""'], {}), "(end_date, '%Y-%m-%d')\n", (55995, 56017), False, 'from datetime import datetime, timedelta\n'), ((56103, 56121), 'datetime.timedelta', 'timedelta', ([], {'days': '(30)'}), '(days=30)\n', (56112, 56121), False, 'from datetime import datetime, timedelta\n'), ((58131, 58171), 'flask.request.args.get', 'request.args.get', (['"""exprSearch"""'], {'type': 'str'}), "('exprSearch', type=str)\n", (58147, 58171), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((58199, 58240), 'flask.request.args.get', 'request.args.get', (['"""indexSearch"""'], {'type': 'str'}), "('indexSearch', type=str)\n", (58215, 58240), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((58261, 58295), 'flask.request.args.get', 'request.args.get', (['"""lang"""'], {'type': 'str'}), "('lang', type=str)\n", (58277, 58295), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((2760, 2796), 'webapp.controllers.get_current_collection', 'controllers.get_current_collection', ([], {}), '()\n', (2794, 2796), False, 'from webapp import controllers\n'), ((3938, 3952), 'flask.session.keys', 'session.keys', ([], {}), '()\n', (3950, 3952), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((4467, 4497), 'flask_babelex.gettext', '_', (['"""Código de idioma inválido"""'], {}), "('Código de idioma inválido')\n", (4468, 4497), True, 'from flask_babelex import gettext as _\n'), ((4922, 4968), 'flask.current_app.config.get', 'current_app.config.get', (['"""BABEL_DEFAULT_LOCALE"""'], {}), "('BABEL_DEFAULT_LOCALE')\n", (4944, 4968), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((6877, 6928), 'webapp.controllers.get_journals', 'controllers.get_journals', ([], {'query_filter': 'query_filter'}), '(query_filter=query_filter)\n', (6901, 6928), False, 'from webapp import controllers\n'), ((8429, 8473), 'flask_babelex.gettext', '_', (['"""Últimos periódicos inseridos na coleção"""'], {}), "('Últimos periódicos inseridos na coleção')\n", (8430, 8473), True, 'from flask_babelex import gettext as _\n'), ((9191, 9254), 'webapp.controllers.get_articles_by_iid', 'controllers.get_articles_by_iid', (['last_issue.iid'], {'is_public': '(True)'}), '(last_issue.iid, is_public=True)\n', (9222, 9254), False, 'from webapp import controllers\n'), ((9762, 9825), 'flask.render_template', 'render_template', (['"""collection/list_feed_content.html"""'], {}), "('collection/list_feed_content.html', **context)\n", (9777, 9825), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((11426, 11495), 'flask_babelex.gettext', '_', (["(u'Requsição inválida ao tentar acessar o artigo com pid: %s' % pid)"], {}), "(u'Requsição inválida ao tentar acessar o artigo com pid: %s' % pid)\n", (11427, 11495), True, 'from flask_babelex import gettext as _\n'), ((14702, 14715), 'flask.redirect', 'redirect', (['"""/"""'], {}), "('/')\n", (14710, 14715), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((15166, 15195), 'flask_babelex.gettext', '_', (['"""Periódico não encontrado"""'], {}), "('Periódico não encontrado')\n", (15167, 15195), True, 'from flask_babelex import gettext as _\n'), ((17426, 17455), 'flask_babelex.gettext', '_', (['"""Periódico não encontrado"""'], {}), "('Periódico não encontrado')\n", (17427, 17455), True, 'from flask_babelex import gettext as _\n'), ((17904, 17937), 'webapp.utils.utils.get_label_issue', 'utils.get_label_issue', (['last_issue'], {}), '(last_issue)\n', (17925, 17937), False, 'from webapp.utils import utils\n'), ((18332, 18391), 'flask.render_template', 'render_template', (['"""issue/feed_content.html"""'], {'article': 'article'}), "('issue/feed_content.html', article=article)\n", (18347, 18391), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((19166, 19195), 'flask_babelex.gettext', '_', (['"""Periódico não encontrado"""'], {}), "('Periódico não encontrado')\n", (19167, 19195), True, 'from flask_babelex import gettext as _\n'), ((20470, 20513), 'flask_babelex.gettext', '_', (['"""Requisição inválida. Deve ser por ajax"""'], {}), "('Requisição inválida. Deve ser por ajax')\n", (20471, 20513), True, 'from flask_babelex import gettext as _\n'), ((21213, 21256), 'flask_babelex.gettext', '_', (['"""Requisição inválida. Deve ser por ajax"""'], {}), "('Requisição inválida. Deve ser por ajax')\n", (21214, 21256), True, 'from flask_babelex import gettext as _\n'), ((21668, 21774), 'webapp.controllers.get_journals_grouped_by', 'controllers.get_journals_grouped_by', (['"""subject_categories"""', 'query'], {'query_filter': 'query_filter', 'lang': 'lang'}), "('subject_categories', query,\n    query_filter=query_filter, lang=lang)\n", (21703, 21774), False, 'from webapp import controllers\n'), ((22383, 22446), 'flask_babelex.gettext', '_', (['"""Parámetro "extension" é inválido, deve ser "csv" ou "xls"."""'], {}), '(\'Parámetro "extension" é inválido, deve ser "csv" ou "xls".\')\n', (22384, 22446), True, 'from flask_babelex import gettext as _\n'), ((22794, 22833), 'flask.request.args.get', 'request.args.get', (['"""query"""', '""""""'], {'type': 'str'}), "('query', '', type=str)\n", (22810, 22833), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((23233, 23266), 'flask.Response', 'Response', (['data'], {'mimetype': 'mimetype'}), '(data, mimetype=mimetype)\n', (23241, 23266), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((23508, 23548), 'flask_babelex.gettext', '_', (['"""Requisição inválida, deve ser ajax."""'], {}), "('Requisição inválida, deve ser ajax.')\n", (23509, 23548), True, 'from flask_babelex import gettext as _\n'), ((23911, 24024), 'webapp.controllers.send_email_contact', 'controllers.send_email_contact', (['recipients', "form.data['name']", "form.data['your_email']", "form.data['message']"], {}), "(recipients, form.data['name'], form.data[\n    'your_email'], form.data['message'])\n", (23941, 24024), False, 'from webapp import controllers\n'), ((24525, 24568), 'flask_babelex.gettext', '_', (['"""Requisição inválida, captcha inválido."""'], {}), "('Requisição inválida, captcha inválido.')\n", (24526, 24568), True, 'from flask_babelex import gettext as _\n'), ((24760, 24789), 'flask_babelex.gettext', '_', (['"""Periódico não encontrado"""'], {}), "('Periódico não encontrado')\n", (24761, 24789), True, 'from flask_babelex import gettext as _\n'), ((25355, 25384), 'flask_babelex.gettext', '_', (['"""Periódico não encontrado"""'], {}), "('Periódico não encontrado')\n", (25356, 25384), True, 'from flask_babelex import gettext as _\n'), ((26810, 26850), 'flask.url_for', 'url_for', (['"""main.aop_toc"""'], {'url_seg': 'url_seg'}), "('main.aop_toc', url_seg=url_seg)\n", (26817, 26850), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((27432, 27472), 'flask.url_for', 'url_for', (['"""main.aop_toc"""'], {'url_seg': 'url_seg'}), "('main.aop_toc', url_seg=url_seg)\n", (27439, 27472), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((27859, 27885), 'flask_babelex.gettext', '_', (['"""Número não encontrado"""'], {}), "('Número não encontrado')\n", (27860, 27885), True, 'from flask_babelex import gettext as _\n'), ((30848, 30895), 'webapp.utils.utils.get_prev_issue', 'utils.get_prev_issue', (['all_issues', 'current_issue'], {}), '(all_issues, current_issue)\n', (30868, 30895), False, 'from webapp.utils import utils\n'), ((31808, 31849), 'flask.request.args.get', 'request.args.get', (['"""section"""', '""""""'], {'type': 'str'}), "('section', '', type=str)\n", (31824, 31849), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((31960, 32003), 'flask_babelex.gettext', '_', (['"""Artigos ahead of print não encontrados"""'], {}), "('Artigos ahead of print não encontrados')\n", (31961, 32003), True, 'from flask_babelex import gettext as _\n'), ((32177, 32200), 'flask.redirect', 'redirect', (['url'], {'code': '(301)'}), '(url, code=301)\n', (32185, 32200), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((32628, 32671), 'flask_babelex.gettext', '_', (['"""Artigos ahead of print não encontrados"""'], {}), "('Artigos ahead of print não encontrados')\n", (32629, 32671), True, 'from flask_babelex import gettext as _\n'), ((34050, 34076), 'flask_babelex.gettext', '_', (['"""Número não encontrado"""'], {}), "('Número não encontrado')\n", (34051, 34076), True, 'from flask_babelex import gettext as _\n'), ((34540, 34568), 'webapp.utils.utils.get_label_issue', 'utils.get_label_issue', (['issue'], {}), '(issue)\n', (34561, 34568), False, 'from webapp.utils import utils\n'), ((34908, 34967), 'flask.render_template', 'render_template', (['"""issue/feed_content.html"""'], {'article': 'article'}), "('issue/feed_content.html', article=article)\n", (34923, 34967), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((35866, 35892), 'flask_babelex.gettext', '_', (['"""Artigo não encontrado"""'], {}), "('Artigo não encontrado')\n", (35867, 35892), True, 'from flask_babelex import gettext as _\n'), ((39212, 39237), 'flask_babelex.gettext', '_', (['"""Issue não encontrado"""'], {}), "('Issue não encontrado')\n", (39213, 39237), True, 'from flask_babelex import gettext as _\n'), ((39521, 39547), 'flask_babelex.gettext', '_', (['"""Artigo não encontrado"""'], {}), "('Artigo não encontrado')\n", (39522, 39547), True, 'from flask_babelex import gettext as _\n'), ((42694, 42715), 'urllib.parse.urlparse', 'urlparse', (['request.url'], {}), '(request.url)\n', (42702, 42715), False, 'from urllib.parse import urlparse\n'), ((43937, 44093), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {'url_seg': 'article.journal.url_segment', 'article_pid_v3': 'article_pid_v3', 'format': '"""xml"""', 'lang': 'article.original_language'}), "('main.article_detail_v3', url_seg=article.journal.url_segment,\n    article_pid_v3=article_pid_v3, format='xml', lang=article.original_language\n    )\n", (43944, 44093), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((44656, 44690), 'webapp.controllers.related_links', 'controllers.related_links', (['article'], {}), '(article)\n', (44681, 44690), False, 'from webapp import controllers\n'), ((45374, 45430), 'flask_babelex.gettext', '_', (['"""Recurso do Artigo não encontrado. Caminho inválido!"""'], {}), "('Recurso do Artigo não encontrado. Caminho inválido!')\n", (45375, 45430), True, 'from flask_babelex import gettext as _\n'), ((46402, 46459), 'flask_babelex.gettext', '_', (['"""Parâmetros insuficientes para obter o EPDF do artigo"""'], {}), "('Parâmetros insuficientes para obter o EPDF do artigo')\n", (46403, 46459), True, 'from flask_babelex import gettext as _\n'), ((48315, 48371), 'flask_babelex.gettext', '_', (['"""Recurso do Artigo não encontrado. Caminho inválido!"""'], {}), "('Recurso do Artigo não encontrado. Caminho inválido!')\n", (48316, 48371), True, 'from flask_babelex import gettext as _\n'), ((49343, 49368), 'flask_babelex.gettext', '_', (['"""Issue não encontrado"""'], {}), "('Issue não encontrado')\n", (49344, 49368), True, 'from flask_babelex import gettext as _\n'), ((49497, 49523), 'flask_babelex.gettext', '_', (['"""Artigo não encontrado"""'], {}), "('Artigo não encontrado')\n", (49498, 49523), True, 'from flask_babelex import gettext as _\n'), ((50157, 50245), 'flask_babelex.gettext', '_', (['"""Este PDF não existe em http://www.scielo.br. Consulte http://search.scielo.org"""'], {}), "('Este PDF não existe em http://www.scielo.br. Consulte http://search.scielo.org'\n    )\n", (50158, 50245), True, 'from flask_babelex import gettext as _\n'), ((50387, 50424), 'flask_babelex.gettext', '_', (['"""PDF do artigo não foi encontrado"""'], {}), "('PDF do artigo não foi encontrado')\n", (50388, 50424), True, 'from flask_babelex import gettext as _\n'), ((51026, 51094), 'flask_babelex.gettext', '_', (["('Requsição inválida ao tentar acessar o artigo com pid: %s' % pid)"], {}), "('Requsição inválida ao tentar acessar o artigo com pid: %s' % pid)\n", (51027, 51094), True, 'from flask_babelex import gettext as _\n'), ((51189, 51215), 'flask_babelex.gettext', '_', (['"""Artigo não encontrado"""'], {}), "('Artigo não encontrado')\n", (51190, 51215), True, 'from flask_babelex import gettext as _\n'), ((51624, 51649), 'flask_babelex.gettext', '_', (['"""Requisição inválida."""'], {}), "('Requisição inválida.')\n", (51625, 51649), True, 'from flask_babelex import gettext as _\n'), ((52779, 52804), 'flask_babelex.gettext', '_', (['"""Requisição inválida."""'], {}), "('Requisição inválida.')\n", (52780, 52804), True, 'from flask_babelex import gettext as _\n'), ((56060, 56074), 'datetime.datetime.now', 'datetime.now', ([], {}), '()\n', (56072, 56074), False, 'from datetime import datetime, timedelta\n'), ((6013, 6077), 'opac_schema.v1.models.Journal.objects.filter', 'Journal.objects.filter', ([], {'is_public': '(True)', 'current_status': '"""current"""'}), "(is_public=True, current_status='current')\n", (6035, 6077), False, 'from opac_schema.v1.models import Journal, Issue, Article, Collection\n'), ((6153, 6191), 'opac_schema.v1.models.Article.objects.filter', 'Article.objects.filter', ([], {'is_public': '(True)'}), '(is_public=True)\n', (6175, 6191), False, 'from opac_schema.v1.models import Journal, Issue, Article, Collection\n'), ((8943, 8957), 'datetime.datetime.now', 'datetime.now', ([], {}), '()\n', (8955, 8957), False, 'from datetime import datetime, timedelta\n'), ((10556, 10582), 'flask_babelex.gettext', '_', (['"""Página não encontrada"""'], {}), "('Página não encontrada')\n", (10557, 10582), True, 'from flask_babelex import gettext as _\n'), ((11613, 11649), 'webapp.controllers.get_journal_by_issn', 'controllers.get_journal_by_issn', (['pid'], {}), '(pid)\n', (11644, 11649), False, 'from webapp import controllers\n'), ((15267, 15294), 'flask_babelex.gettext', '_', (['journal.unpublish_reason'], {}), '(journal.unpublish_reason)\n', (15268, 15294), True, 'from flask_babelex import gettext as _\n'), ((17527, 17554), 'flask_babelex.gettext', '_', (['journal.unpublish_reason'], {}), '(journal.unpublish_reason)\n', (17528, 17554), True, 'from flask_babelex import gettext as _\n'), ((18291, 18313), 'flask_babelex.gettext', '_', (['"""Artigo sem título"""'], {}), "('Artigo sem título')\n", (18292, 18313), True, 'from flask_babelex import gettext as _\n'), ((19267, 19294), 'flask_babelex.gettext', '_', (['journal.unpublish_reason'], {}), '(journal.unpublish_reason)\n', (19268, 19294), True, 'from flask_babelex import gettext as _\n'), ((21821, 21924), 'webapp.controllers.get_journals_grouped_by', 'controllers.get_journals_grouped_by', (['"""publisher_name"""', 'query'], {'query_filter': 'query_filter', 'lang': 'lang'}), "('publisher_name', query, query_filter=\n    query_filter, lang=lang)\n", (21856, 21924), False, 'from webapp import controllers\n'), ((22541, 22634), 'flask_babelex.gettext', '_', (['"""Parámetro "list_type" é inválido, deve ser: "alpha", "areas", "wos" ou "publisher"."""'], {}), '(\'Parámetro "list_type" é inválido, deve ser: "alpha", "areas", "wos" ou "publisher".\'\n    )\n', (22542, 22634), True, 'from flask_babelex import gettext as _\n'), ((23767, 23809), 'flask_babelex.gettext', '_', (['"""Periódico não permite envio de email."""'], {}), "('Periódico não permite envio de email.')\n", (23768, 23809), True, 'from flask_babelex import gettext as _\n'), ((25456, 25483), 'flask_babelex.gettext', '_', (['journal.unpublish_reason'], {}), '(journal.unpublish_reason)\n', (25457, 25483), True, 'from flask_babelex import gettext as _\n'), ((27682, 27723), 'flask.request.args.get', 'request.args.get', (['"""section"""', '""""""'], {'type': 'str'}), "('section', '', type=str)\n", (27698, 27723), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((27952, 27977), 'flask_babelex.gettext', '_', (['issue.unpublish_reason'], {}), '(issue.unpublish_reason)\n', (27953, 27977), True, 'from flask_babelex import gettext as _\n'), ((28099, 28126), 'flask_babelex.gettext', '_', (['journal.unpublish_reason'], {}), '(journal.unpublish_reason)\n', (28100, 28126), True, 'from flask_babelex import gettext as _\n'), ((32307, 32334), 'flask_babelex.gettext', '_', (['journal.unpublish_reason'], {}), '(journal.unpublish_reason)\n', (32308, 32334), True, 'from flask_babelex import gettext as _\n'), ((34144, 34169), 'flask_babelex.gettext', '_', (['issue.unpublish_reason'], {}), '(issue.unpublish_reason)\n', (34145, 34169), True, 'from flask_babelex import gettext as _\n'), ((34247, 34280), 'flask_babelex.gettext', '_', (['issue.journal.unpublish_reason'], {}), '(issue.journal.unpublish_reason)\n', (34248, 34280), True, 'from flask_babelex import gettext as _\n'), ((41174, 41197), 'flask_babelex.gettext', '_', (['"""Artigo inexistente"""'], {}), "('Artigo inexistente')\n", (41175, 41197), True, 'from flask_babelex import gettext as _\n'), ((41318, 41344), 'flask_babelex.gettext', '_', (['"""Artigo não encontrado"""'], {}), "('Artigo não encontrado')\n", (41319, 41344), True, 'from flask_babelex import gettext as _\n'), ((41432, 41536), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {'url_seg': 'url_seg', 'article_pid_v3': 'article_pid_v3', 'format': 'qs_format'}), "('main.article_detail_v3', url_seg=url_seg, article_pid_v3=\n    article_pid_v3, format=qs_format)\n", (41439, 41536), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((41715, 41742), 'flask_babelex.gettext', '_', (['"""Recurso não encontrado"""'], {}), "('Recurso não encontrado')\n", (41716, 41742), True, 'from flask_babelex import gettext as _\n'), ((42310, 42443), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {'url_seg': 'article.journal.url_segment', 'article_pid_v3': 'article_pid_v3', 'lang': 'qs_lang', 'format': '"""pdf"""'}), "('main.article_detail_v3', url_seg=article.journal.url_segment,\n    article_pid_v3=article_pid_v3, lang=qs_lang, format='pdf')\n", (42317, 42443), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((44909, 44942), 'flask_babelex.gettext', '_', (['"""PDF do Artigo não encontrado"""'], {}), "('PDF do Artigo não encontrado')\n", (44910, 44942), True, 'from flask_babelex import gettext as _\n'), ((45074, 45107), 'flask_babelex.gettext', '_', (['"""PDF do Artigo não encontrado"""'], {}), "('PDF do Artigo não encontrado')\n", (45075, 45107), True, 'from flask_babelex import gettext as _\n'), ((46936, 46959), 'flask_babelex.gettext', '_', (['"""PDF não encontrado"""'], {}), "('PDF não encontrado')\n", (46937, 46959), True, 'from flask_babelex import gettext as _\n'), ((47007, 47027), 'flask_babelex.gettext', '_', (['"""Erro inesperado"""'], {}), "('Erro inesperado')\n", (47008, 47027), True, 'from flask_babelex import gettext as _\n'), ((47521, 47548), 'flask_babelex.gettext', '_', (['"""Recurso não encontrado"""'], {}), "('Recurso não encontrado')\n", (47522, 47548), True, 'from flask_babelex import gettext as _\n'), ((47596, 47616), 'flask_babelex.gettext', '_', (['"""Erro inesperado"""'], {}), "('Erro inesperado')\n", (47597, 47616), True, 'from flask_babelex import gettext as _\n'), ((52923, 52978), 'flask.current_app.config.get', 'current_app.config.get', (['"""EMAIL_ACCOUNTS_RECEIVE_ERRORS"""'], {}), "('EMAIL_ACCOUNTS_RECEIVE_ERRORS')\n", (52945, 52978), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((55498, 55548), 'flask.url_for', 'url_for', (['"""main.about_journal"""'], {'url_seg': 'journal_seg'}), "('main.about_journal', url_seg=journal_seg)\n", (55505, 55548), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((58081, 58107), 'flask_babelex.gettext', '_', (['"""Página não encontrada"""'], {}), "('Página não encontrada')\n", (58082, 58107), True, 'from flask_babelex import gettext as _\n'), ((3634, 3679), 'flask.current_app.config.get', 'current_app.config.get', (['"""SCIELO_ORG_URIS"""', '{}'], {}), "('SCIELO_ORG_URIS', {})\n", (3656, 3679), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((11881, 11940), 'flask.url_for', 'url_for', (['"""main.journal_detail"""'], {'url_seg': 'journal.url_segment'}), "('main.journal_detail', url_seg=journal.url_segment)\n", (11888, 11940), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((12045, 12078), 'webapp.controllers.get_issue_by_pid', 'controllers.get_issue_by_pid', (['pid'], {}), '(pid)\n', (12073, 12078), False, 'from webapp import controllers\n'), ((23094, 23108), 'datetime.datetime.now', 'datetime.now', ([], {}), '()\n', (23106, 23108), False, 'from datetime import datetime, timedelta\n'), ((40377, 40420), 'flask_babelex.gettext', '_', (['"""Não existe \'{}\'. No seu lugar use \'{}\'"""'], {}), '("Não existe \'{}\'. No seu lugar use \'{}\'")\n', (40378, 40420), True, 'from flask_babelex import gettext as _\n'), ((41130, 41153), 'flask_babelex.gettext', '_', (['"""Resumo inexistente"""'], {}), "('Resumo inexistente')\n", (41131, 41153), True, 'from flask_babelex import gettext as _\n'), ((43215, 43265), 'flask_babelex.gettext', '_', (['"""HTML do Artigo não encontrado ou indisponível"""'], {}), "('HTML do Artigo não encontrado ou indisponível')\n", (43216, 43265), True, 'from flask_babelex import gettext as _\n'), ((43321, 43341), 'flask_babelex.gettext', '_', (['"""Erro inesperado"""'], {}), "('Erro inesperado')\n", (43322, 43341), True, 'from flask_babelex import gettext as _\n'), ((43466, 43498), 'webapp.config.lang_names.display_original_lang_name', 'display_original_lang_name', (['lang'], {}), '(lang)\n', (43492, 43498), False, 'from webapp.config.lang_names import display_original_lang_name\n'), ((43523, 43639), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {'url_seg': 'article.journal.url_segment', 'article_pid_v3': 'article_pid_v3', 'lang': 'lang'}), "('main.article_detail_v3', url_seg=article.journal.url_segment,\n    article_pid_v3=article_pid_v3, lang=lang)\n", (43530, 43639), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((45249, 45282), 'flask_babelex.gettext', '_', (['"""PDF do Artigo não encontrado"""'], {}), "('PDF do Artigo não encontrado')\n", (45250, 45282), True, 'from flask_babelex import gettext as _\n'), ((45957, 45983), 'flask_babelex.gettext', '_', (['"""Formato não suportado"""'], {}), "('Formato não suportado')\n", (45958, 45983), True, 'from flask_babelex import gettext as _\n'), ((11706, 11735), 'flask_babelex.gettext', '_', (['"""Periódico não encontrado"""'], {}), "('Periódico não encontrado')\n", (11707, 11735), True, 'from flask_babelex import gettext as _\n'), ((12616, 12714), 'flask.url_for', 'url_for', (['"""main.issue_toc"""'], {'url_seg': 'issue.journal.url_segment', 'url_seg_issue': 'issue.url_segment'}), "('main.issue_toc', url_seg=issue.journal.url_segment, url_seg_issue=\n    issue.url_segment)\n", (12623, 12714), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((12903, 12941), 'webapp.controllers.get_article_by_pid_v2', 'controllers.get_article_by_pid_v2', (['pid'], {}), '(pid)\n', (12936, 12941), False, 'from webapp import controllers\n'), ((22004, 22079), 'flask_babelex.gettext', '_', (['"""Parámetro "filter" é inválido, deve ser "areas", "wos" ou "publisher"."""'], {}), '(\'Parámetro "filter" é inválido, deve ser "areas", "wos" ou "publisher".\')\n', (22005, 22079), True, 'from flask_babelex import gettext as _\n'), ((11823, 11850), 'flask_babelex.gettext', '_', (['journal.unpublish_reason'], {}), '(journal.unpublish_reason)\n', (11824, 11850), True, 'from flask_babelex import gettext as _\n'), ((12133, 12159), 'flask_babelex.gettext', '_', (['"""Número não encontrado"""'], {}), "('Número não encontrado')\n", (12134, 12159), True, 'from flask_babelex import gettext as _\n'), ((12518, 12558), 'flask.url_for', 'url_for', (['"""main.aop_toc"""'], {'url_seg': 'url_seg'}), "('main.aop_toc', url_seg=url_seg)\n", (12525, 12558), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((13311, 13435), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {'url_seg': 'article.journal.url_segment', 'article_pid_v3': 'article.aid', 'part': 'part', 'lang': 'tlng'}), "('main.article_detail_v3', url_seg=article.journal.url_segment,\n    article_pid_v3=article.aid, part=part, lang=tlng)\n", (13318, 13435), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((13680, 13716), 'webapp.controllers.get_journal_by_issn', 'controllers.get_journal_by_issn', (['pid'], {}), '(pid)\n', (13711, 13716), False, 'from webapp import controllers\n'), ((12243, 12268), 'flask_babelex.gettext', '_', (['issue.unpublish_reason'], {}), '(issue.unpublish_reason)\n', (12244, 12268), True, 'from flask_babelex import gettext as _\n'), ((12362, 12395), 'flask_babelex.gettext', '_', (['issue.journal.unpublish_reason'], {}), '(issue.journal.unpublish_reason)\n', (12363, 12395), True, 'from flask_babelex import gettext as _\n'), ((12997, 13023), 'flask_babelex.gettext', '_', (['"""Artigo não encontrado"""'], {}), "('Artigo não encontrado')\n", (12998, 13023), True, 'from flask_babelex import gettext as _\n'), ((13948, 14003), 'flask.url_for', 'url_for', (['"""main.issue_grid"""'], {'url_seg': 'journal.url_segment'}), "('main.issue_grid', url_seg=journal.url_segment)\n", (13955, 14003), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((14147, 14185), 'webapp.controllers.get_article_by_pid_v2', 'controllers.get_article_by_pid_v2', (['pid'], {}), '(pid)\n', (14180, 14185), False, 'from webapp import controllers\n'), ((13773, 13802), 'flask_babelex.gettext', '_', (['"""Periódico não encontrado"""'], {}), "('Periódico não encontrado')\n", (13774, 13802), True, 'from flask_babelex import gettext as _\n'), ((14315, 14431), 'flask.url_for', 'url_for', (['"""main.article_detail_v3"""'], {'url_seg': 'article.journal.url_segment', 'article_pid_v3': 'article.aid', 'format': '"""pdf"""'}), "('main.article_detail_v3', url_seg=article.journal.url_segment,\n    article_pid_v3=article.aid, format='pdf')\n", (14322, 14431), False, 'from flask import render_template, abort, current_app, request, session, redirect, jsonify, url_for, Response, send_from_directory, g, make_response\n'), ((14605, 14674), 'flask_babelex.gettext', '_', (["(u'Requsição inválida ao tentar acessar o artigo com pid: %s' % pid)"], {}), "(u'Requsição inválida ao tentar acessar o artigo com pid: %s' % pid)\n", (14606, 14674), True, 'from flask_babelex import gettext as _\n'), ((13890, 13917), 'flask_babelex.gettext', '_', (['journal.unpublish_reason'], {}), '(journal.unpublish_reason)\n', (13891, 13917), True, 'from flask_babelex import gettext as _\n'), ((14241, 14267), 'flask_babelex.gettext', '_', (['"""Artigo não encontrado"""'], {}), "('Artigo não encontrado')\n", (14242, 14267), True, 'from flask_babelex import gettext as _\n')]