Skip to content

Instantly share code, notes, and snippets.

@uribo
Last active October 11, 2019 07:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uribo/1af2733c02da57a86d0493b6c4126e56 to your computer and use it in GitHub Desktop.
Save uribo/1af2733c02da57a86d0493b6c4126e56 to your computer and use it in GitHub Desktop.
library(rlang)
library(purrr, warn.conflicts = FALSE)
library(glue)
library(rAltmetric)
# library(ghql)
reference_style <- "oikos"
path_references_bib <- "references.bib"
qry <- ghql::Query$new()
cli <- ghql::GraphqlClient$new(
url = "https://api.github.com/graphql",
headers = httr::add_headers(Authorization = paste0("Bearer ", GITHUB_PAT))
)
cli$load_schema()
event_json <- jsonlite::fromJSON(path2event_json)
user <- event_json$repository$owner$login
repo <- event_json$repository$name
current_labels <-
event_json$issue$labels$name
# Functions ---------------------------------------------------------------
round_journal_name <- function(x) {
gsub("\\{\\\\", "", x) %>%
gsub("}", "", .) %>%
gsub("\\{", "", .) %>%
gsub("Journal", "J.", .) %>%
stringr::str_replace("Proceedings of the National Academy of Sciences", "PNAS")
}
check_duplicate <- function(issue_title, issue_list, event_json, close = FALSE, user = user, repo = repo) {
duplicate_num <-
subset(issue_list, title == issue_title) %>%
purrr::pluck("number")
if (rlang::is_false(is.null(duplicate_num)) & rlang::is_true(close)) {
gh::gh("PATCH /repos/:owner/:repo/issues/:number",
owner = user,
repo = repo,
number = event_json$issue$number,
body = glue("Duplicate #{duplicate_num}"),
labels = list("duplicate"),
state = "closed")
}
duplicate_num
}
identific_altmetrics <-
function(type = NULL, identifer = NULL) {
args <-
list(doi = ifelse(type == "DOI", identifer, NA),
arxiv = ifelse(type == "arxiv", identifer, NA)) %>%
purrr::keep(~ !is.na(.x))
res_altm <-
rlang::exec("altmetrics", !!!args)
df_res_altm <-
rAltmetric::altmetric_data(res_altm)
vars_altm <-
names(df_res_altm)[names(df_res_altm) %in% c(
"cited_by_posts_count",
"cited_by_tweeters_count",
"cited_by_accounts_count",
"score",
"last_updated")]
df_res_altm <-
df_res_altm[, vars_altm]
df_res_altm$last_updated <-
as.POSIXct(as.numeric(df_res_altm$last_updated),
origin = "1970-01-01 00:00:00",
tz = "UTC")
altmetric_score <-
df_res_altm %>%
knitr::kable() %>%
as.character() %>%
paste(collapse = "\n")
altmetric_url <-
res_altm$details_url
list(score = altmetric_score, url = altmetric_url)
}
# 1. Create issue template ------------------------------------------------
path_issue_template <- ".github/ISSUE_TEMPLATE/paper_template.md"
queries <- list(issue_template = list("data", "repository", "object"),
issue_count = list("data", "repository", "issues", "totalCount"),
exist_bibfile = list("data", "repository", "object"),
collect_article_issue = list("data", "repository", "issues", "edges", "node"))
qry$query("issue_template",
glue('
query{
repository(owner: "<user>",name: "<repo>"){
object(expression: "master:<path_issue_template>") {
... on Blob {
text
}
}
}
}',
.open = "<",
.close = ">"))
is_issue_template_exist <-
negate(
~ jsonlite::fromJSON(.x) %>%
## purrr::map_depth(3, ~ is.null(.x)) ... same
pluck(!!! queries %>%
pluck("issue_template")) %>%
is.null()
)(cli$exec(qry$queries$issue_template))
if (rlang::is_false(is_issue_template_exist)) {
issue_template_base64 <-
openssl::base64_encode("---
name: paper_template
about: Issue for papers.
title: 'DOI / arXiv: <identifier>'
labels: papers
assignees: ''
---
## Summary
## Description
### :flashlight: Highlights
### :game_die: Approach
### :hatching_chick: Results
### :speech_balloon: Comments")
# openssl::base64_decode(issue_template_base64) %>%
# rawToChar() %>%
# cat()
gh::gh("PUT /repos/:owner/:repo/contents/:path",
owner = user,
repo = repo,
path = path_issue_template,
message = "Added paper template",
content = issue_template_base64)
}
# 2. Update article information -------------------------------------------
issue_title <- event_json$issue$title
paper_type <-
ifelse(grepl("arxiv", issue_title, ignore.case = TRUE),
"arxiv",
ifelse(grepl("doi", issue_title, ignore.case = TRUE),
"DOI",
rlang::warn("Can't detect DOI or arXiv identifer")))
if (paper_type %in% c("arxiv", "DOI")) {
qry$query("issue_count",
glue(
'query {
repository(owner: "<user>", name: "<repo>") {
issues {
totalCount
}
}
}',
.open = "<",
.close = ">"
))
issue_count <-
cli$exec(qry$queries$issue_count) %>%
jsonlite::fromJSON() %>%
pluck(!!! queries %>%
purrr::pluck("issue_count"))
qry$query("collect_article_issue",
glue(
'query {
repository(owner: "<user>", name: "<repo>") {
issues (labels: "papers", first: <issue_count>) {
edges {
node {
title,
number
}
}
}
}
}
',
.open = "<",
.close = ">"))
df_issues <-
cli$exec(qry$queries$collect_article_issue) %>%
jsonlite::fromJSON() %>%
pluck(!!! queries %>%
pluck("collect_article_issue"))
# req_issue_list <-
# gh::gh("GET /repos/:owner/:repo/issues",
# owner = event_json$sender$login,
# repo = event_json$repository$name)
# df_issues <-
# data.frame(
# number = req_issue_list %>%
# purrr::map_chr(c("number")),
# title = req_issue_list %>%
# purrr::map_chr(c("title")), stringsAsFactors = FALSE)
paper_identifer <-
gsub("[[:space:]]", "", gsub(".+:", "", issue_title))
if (paper_type == "arxiv") {
paper_identifer <- gsub("v.+", "", paper_identifer)
}
altm_status <-
httr::status_code(httr::GET(glue("http://api.altmetric.com/v1/{paper_type}/{paper_identifer}")))
if (paper_type == "arxiv") {
if (rlang::is_true(httr:::http_error(glue("https://arxiv.org/abs/{paper_identifer}")))) {
gh::gh("POST /repos/:owner/:repo/issues/:number/comments",
owner = user,
repo = repo,
number = event_json$issue$number,
body = "Article identifier not recognized. Please, check identifier.")
} else {
target_article <-
aRxiv::arxiv_search(id_list = paper_identifer, sep = ", ", limit = 1)
authors <- target_article$authors
title <- target_article$title
url <- target_article$link_abstract
submited_year <- substr(target_article$submitted, 1, 4)
abstract <- target_article$abstract
issue_title <-
paste(
paste(
gsub(pattern = "[[:space:]].+", "", authors),
submited_year,
sep = "_"
),
title, sep = ": ")
duplicate_num <-
check_duplicate(issue_title, df_issues, event_json, close = FALSE, user, repo)
}
} else if (paper_type == "DOI") {
target_article <-
rcrossref::cr_cn(dois = paper_identifer,
format = "bibtex",
style = reference_style)
if (is.null(target_article)) {
gh::gh("POST /repos/:owner/:repo/issues/:number/comments",
owner = user,
repo = repo,
number = event_json$issue$number,
body = "DOI Not Found. Please, check identifier.")
} else {
target_article_parsed <-
rcrossref:::parse_bibtex(target_article)
authors <- ifelse(is.null(target_article_parsed$author), "", target_article_parsed$author)
title <- round_journal_name(target_article_parsed$title)
url <- target_article_parsed$url
issue_title <- glue("{key}: {title}",
key = target_article_parsed$key)
duplicate_num <-
check_duplicate(issue_title, df_issues, event_json, close = FALSE, user, repo)
}
}
# Added article information -----------------------------------------------
if (!is.null(target_article) & is.null(duplicate_num)) {
if (paper_type == "arxiv") {
issue_labels <-
list(paste("Journal:", "arXiv"),
paste("Published year:", submited_year),
paste("Category:", target_article$primary_category))
res_altm <-
rAltmetric::altmetrics(arxiv = paper_identifer)
issue_body <-
glue(
"## Information\n
:page_with_curl: Title: **{title}**
:busts_in_silhouette: Authors: {authors}
:link: URL: [{url}]({url})
:date: Submitted: {submit_time} (Update: {update_time})\n
### Abstract\n
```
{abstract}
```",
submit_time = as.POSIXct(target_article$submitted, tz = "UTC"),
update_time = as.POSIXct(target_article$updated, tz = "UTC"))
} else if (paper_type == "DOI") {
issue_labels <-
list(paste("Journal:", round_journal_name(target_article_parsed$journal)),
paste("Published year:", target_article_parsed$year),
paste("Type:", target_article_parsed$entry))
issue_body <-
glue(
"## Information\n
:page_with_curl: Title: **{title}**
:busts_in_silhouette: Authors: {authors}
:link: URL: [{url}]({url})
:date: {month} {year} (Volume{volume}{number})
",
year = target_article_parsed$year,
month = month.name[which(grepl(target_article_parsed$month, month.abb, ignore.case = TRUE))],
volume = ifelse(is.null(target_article_parsed$volume),
"",
target_article_parsed$volume),
number = ifelse(is.null(target_article_parsed$number), "",
paste0(" #&#x2060;", target_article_parsed$number)))
}
# Modified issue title and assigned label ---------------------------------
issue_labels <-
purrr::list_modify(issue_labels, !!!as.list(current_labels) %>%
purrr::set_names(current_labels)) %>%
purrr::set_names(NULL) %>%
purrr::keep(~ nchar(.x) <= 50)
gh::gh("PATCH /repos/:owner/:repo/issues/:number",
owner = user,
repo = repo,
number = event_json$issue$number,
title = issue_title,
labels = issue_labels)
if (identical(altm_status, 200L)) {
res_altm <-
identific_altmetrics(type = paper_type, identifer = paper_identifer)
issue_body <-
glue(
issue_body,
"\n\n",
glue(
'### Article metrics\n
{score}\n
{url}',
score = res_altm$score,
url = res_altm$url),
.open = "AAA",
.close = "ZZZ")
}
gh::gh("POST /repos/:owner/:repo/issues/:number/comments",
owner = user,
repo = repo,
number = event_json$issue$number,
body = issue_body)
if (paper_type == "DOI") {
qry$query("exist_bibfile",
glue('
query{
repository(owner: "<user>",name: "<repo>"){
object(expression: "master:<path_references_bib>") {
... on Blob {
text
}
}
}
}',
.open = "<",
.close = ">"))
is_bibfile_exist <-
negate(
~ jsonlite::fromJSON(.x) %>%
pluck(!!! queries %>%
pluck("exist_bibfile")) %>%
is.null()
)(cli$exec(qry$queries$exist_bibfile))
if (rlang::is_true(is_bibfile_exist)) {
get_bib <-
gh::gh("GET /repos/:owner/:repo/contents/:path",
owner = user,
repo = repo,
path = path_references_bib)
reference_bibtex_base64 <-
paste(get_bib$content %>%
openssl::base64_decode(text = .) %>%
rawToChar(),
target_article,
sep = "\n") %>%
openssl::base64_encode(bin = .)
gh::gh("PUT /repos/:owner/:repo/contents/:path",
owner = user,
repo = repo,
path = path_references_bib,
content = reference_bibtex_base64,
message = glue("Update crossref citations by #{number}",
number = event_json$issue$number),
sha = get_bib$sha)
} else {
reference_bibtex_base64 <-
openssl::base64_encode(paste0(target_article, "\n"))
gh::gh("PUT /repos/:owner/:repo/contents/:path",
owner = user,
repo = repo,
path = path_references_bib,
content = reference_bibtex_base64,
message = glue("Add crossref citations by #{number}",
number = event_json$issue$number))
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment