def summary():
  error = ''
  respheaders = None
  results = None

  try:
    results, respheaders = helpers.rxapi(f"/v1/data/summary", headers=True)
  except Exception as e:
    print(e)
    error = f"Sorry—there was a problem retrieving the results: {e}"
    bottle.response.status = 500

  # Figure out the top categories:
  top_cats = []
  for cat in results['submissions_categorical']:
    top_cats.append({
      'category': cat['label'],
      'count': cat['data'][-1]['count']
    })

  def sorter(x):
    # little helper function that sorts the categories
    # based on the most recent month's submissions
    return x['count']
  top_cats = sorted(top_cats, key=sorter, reverse=True)

  stats = helpers.rxapi("/v1/data/stats")

  return bottle.template('summary', results=results,
    top_cats=top_cats,
    error=error, stats=stats, google_tag=config.google_tag)
def display_author_details(id):
  try:
    get = requests.get(f"{config.rxapi}/v1/authors/{id}")
    if get.status_code == 404:
      raise helpers.NotFoundError(id)
    # make sure the URL we ended at matches the URL we asked for:
    new_id = re.search('/(\d+)$', get.url)
    if new_id and len(new_id.groups()) > 0:
      try:
        new_id = int(new_id.group(1))
      except Exception:
        bottle.response.status = 500
        return {"error": "Server errror."}
      if new_id != id: # if we got redirected to a new URL
        return bottle.redirect(f"{config.host}/authors/{new_id}", 301)
    author = get.json()
  except helpers.NotFoundError as e:
    bottle.response.status = 404
    return e.message
  except ValueError as e:
    bottle.response.status = 500
    print(e)
    return {"error": "Server error."}

  distro = helpers.rxapi("/v1/data/distributions/author/downloads")
  download_distribution = distro["histogram"]
  averages = distro["averages"]
  stats = helpers.rxapi("/v1/data/stats")
  return bottle.template('author_details', author=author,
    download_distribution=download_distribution, averages=averages, stats=stats,
    google_tag=config.google_tag)
def topyear(year):
  error = ''
  respheaders = None
  results = None

  if year < 2013:
    error = "Lists currently available only for 2013 through 2018."
    bottle.response.status = 404

  try:
    results, respheaders = helpers.rxapi(f"/v1/top/{year}", headers=True)
  except Exception as e:
    print(e)
    error = f"Sorry&mdash;there was a problem retrieving the results: {e}"
    bottle.response.status = 500

  # if respheaders is not None and "Cache-Control" in respheaders.keys():
  #   bottle.response.set_header("Cache-Control", respheaders["Cache-Control"])
  bottle.response.set_header("Cache-Control", 'max-age=600, stale-while-revalidate=172800')

  stats = helpers.rxapi("/v1/data/stats")

  yearstats = { # TODO: Put this in the API
    2013: {
      "papers": 109,
      "downloads": 17268
    },
    2014: {
      "papers": 886,
      "downloads": 311046
    },
    2015: {
      "papers": 1774,
      "downloads": 679159
    },
    2016: {
      "papers": 4718,
      "downloads": 2182836
    },
    2017: {
      "papers": 11342,
      "downloads": 3995108
    },
    2018: {
      "papers": 20050,
      "downloads": 5730324
    }
  }

  return bottle.template('top_year', results=results['results'],
    year=year, yearpapers=yearstats[year]['papers'], yeardownloads = yearstats[year]['downloads'],
    error=error, stats=stats, google_tag=config.google_tag)
Exemple #4
0
def build_docs():
    category_list = helpers.rxapi("/v1/data/categories")[
        "results"]  # list of all article categories

    return docmodels.Documentation("https://api.rxivist.org/v1", [
        papers(category_list),
        authors(category_list),
        apidetails(),
    ])
def display_paper_details(paper_id):
  try:
    paper = requests.get(f"{config.rxapi}/v1/papers/{paper_id}")
  except helpers.NotFoundError as e:
    bottle.response.status = 404
    return e.message
  except ValueError as e:
    bottle.response.status = 500
    print(e)
    return {"error": "Server error."}

  # make sure the URL we ended at matches the URL we asked for:
  new_id = re.search('/(\d+)$', paper.url)
  if new_id and len(new_id.groups()) > 0:
    try:
      new_id = str(new_id.group(1))
      paper_id = str(paper_id)
    except Exception:
      bottle.response.status = 500
      return {"error": "Server error."}
    if new_id != paper_id: # if we got redirected to a new URL
      return bottle.redirect(f"{config.host}/papers/{new_id}", 301)

  paper = paper.json()
  downloads = helpers.rxapi(f"/v1/downloads/{paper_id}")["results"]
  # Convert the API response into something we can pass to the generic
  # template for the graph:
  traffic = [{
    'month': x['month'], 'year': x['year'], 'count': x['downloads']
  } for x in downloads]

  distro = helpers.rxapi("/v1/data/distributions/paper/downloads")
  download_distribution = distro["histogram"]
  averages = distro["averages"]
  stats = helpers.rxapi("/v1/data/stats")
  return bottle.template('paper_details', paper=paper, traffic=traffic,
    download_distribution=download_distribution, averages=averages, stats=stats,
    google_tag=config.google_tag)
def index():
  error = ""
  view = bottle.request.query.view
  if view is None or view not in ["standard", "print"]:
    view = "standard"
  entity = bottle.request.query.entity
  if entity is None or entity == "":
    entity = "papers"
  category_list = helpers.rxapi("/v1/data/categories")["results"]
  stats = helpers.rxapi("/v1/data/stats")
  results = {} # a list of articles for the current page
  respheaders = None

  try:
    if entity == "authors":
      category_filter = bottle.request.query.getall('category')
      if len(category_filter) == 0:
        category = ""
      else:
        category = category_filter[0] # just one category for author ranks for now
        category_filter = [category_filter[0]]
      results = helpers.rxapi(f"/v1/authors?category={category}")
    elif entity == "papers":
      results, respheaders = helpers.rxapi(f"/v1/papers?{bottle.request.query_string}", headers=True)
  except Exception as e:
    print(e)
    error = f"There was a problem with the submitted query: {e}"
    bottle.response.status = 500

  # Take the current query string and turn it into a template that any page
  # number can get plugged into:
  if "page=" in bottle.request.query_string:
    pagelink =  "/?{}".format(re.sub(r"page=\d*", "page=", bottle.request.query_string))
  else:
    pagelink = f"/?{bottle.request.query_string}&page="


  metric = ""
  timeframe = ""
  page = ""
  page_size = ""
  totalcount = ""
  query = ""

  if entity == "papers":
    try:
      metric = results["query"]["metric"]
      timeframe = results["query"]["timeframe"]
      category_filter = results["query"]["categories"]
      page = results["query"]["current_page"]
      page_size = results["query"]["page_size"]
      totalcount = results["query"]["total_results"]
      query = results["query"]["text_search"]
    except Exception as e:
      if "error" in results.keys():
        error = results["error"]
      else:
        error = str(e) # TODO: this is bad
      return error

  results = results["results"]

  # figure out the page title
  if entity == "papers":
    title = "Most "
    if metric == "twitter":
      title += "tweeted"
    elif metric == "downloads":
      title += "downloaded"
    if query != "":
      title += f" papers related to \"{query},\" "
    else:
      title += " bioRxiv papers, "
    printable_times = {
      "alltime": "all time",
      "ytd": "year to date",
      "lastmonth": "since beginning of last month",
      "day": "last 24 hours",
      "week": "last 7 days",
      "month": "last 30 days",
      "year": "last 365 days"
    }
    title += printable_times[timeframe]
  elif entity == "authors":
    title = "Authors with most downloads, all-time"

  if bottle.request.query_string == "":
    bottle.response.set_header("Cache-Control", f"max-age={config.front_page_cache}, stale-while-revalidate=172800")
  # use whatever cache-control headers are sent to us from the API
  if respheaders is not None and "Cache-Control" in respheaders.keys():
    bottle.response.set_header("Cache-Control", respheaders["Cache-Control"])

  temp = 'print' if view == "print" else 'index'
  return bottle.template(temp, results=results,
    query=query, category_filter=category_filter, title=title,
    error=error, stats=stats, category_list=category_list, view=view,
    timeframe=timeframe, metric=metric, entity=entity, google_tag=config.google_tag,
    page=page, page_size=page_size, totalcount=totalcount, pagelink=pagelink,
    querystring=bottle.request.query_string)
def api_docs():
  stats = helpers.rxapi("/v1/data/stats")
  documentation = docs.build_docs()
  return bottle.template("api_docs", google_tag=config.google_tag, stats=stats, docs=documentation)
def privacy():
  stats = helpers.rxapi("/v1/data/stats")
  return bottle.template("newsletter", google_tag=config.google_tag, stats=stats)
def emailcode():
  results, _ = helpers.rxapi(f"/v1/papers?timeframe=week&page_size=20", headers=True)
  results = results["results"]
  bottle.response.set_header("Cache-Control", f"max-age=0, stale-while-revalidate=0")

  return bottle.template('emailtemplate', results=results)