Skip to content

Commit

Permalink
Merge pull request #10 from davibarreira/zenodo
Browse files Browse the repository at this point in the history
Implemented Getting Zenodo citation
  • Loading branch information
SebastianM-C authored Jun 21, 2021
2 parents 8256957 + d4b4ea6 commit e6bbf4e
Show file tree
Hide file tree
Showing 9 changed files with 963 additions and 11 deletions.
6 changes: 5 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ authors = ["Sebastian Micluța-Câmpeanu <[email protected]>"]
version = "0.1.0"

[deps]
BibParser = "13533e5b-e1c2-4e57-8cef-cac5e52f6474"
Bibliography = "f1be7e48-bf82-45af-a471-ae754a193061"
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[compat]
DataStructures = "0.18"
Bibliography = "0.2"
BibParser = "0.1"
DataStructures = "0.18"
HTTP = "0.9"
julia = "1.6"

[extras]
Expand Down
2 changes: 2 additions & 0 deletions src/PkgCite.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import Pkg
using Bibliography: import_bibtex, export_bibtex, Entry
using DataStructures
using InteractiveUtils
using BibParser: parse_entry
using HTTP

const DEFAULT_CITE = "\\cite"

Expand Down
74 changes: 67 additions & 7 deletions src/citations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,32 +5,43 @@ function citation_path(pkg)
end
end

function get_citation(pkg)

# Added `badge` flag to avoid breaking current tests
function get_citation(pkg; badge=false)
bib_path = citation_path(pkg)
if badge == false
urlbadge = nothing
else
urlbadge = get_badge(pkg)
end
if !isnothing(bib_path)
@debug "Reading CITATION.bib for $(pkg.name)"
try
import_bibtex(bib_path)
catch e
@warn "There was an error reading the CITATION.bib file for $(pkg.name)" exception=e
end
elseif !isnothing(urlbadge)
get_citation_badge(urlbadge)
end
end

"""
collect_citations(only_direct::Bool)
collect_citations(only_direct::Bool; badge=false)
Collect the citations from all the dependencies in the current environment.
Use `badge = true` to get the citations from packages without
a `Citation.bib` file, but with a DOI badge.
"""
function collect_citations(only_direct::Bool)
function collect_citations(only_direct::Bool; badge=false)
@debug "Generating citation report for the current environment"
deps = Pkg.dependencies()
pkg_citations = Dict{String, DataStructures.OrderedDict{String,Entry}}()
for pkg in values(deps)
if only_direct && !pkg.is_direct_dep
continue
end
c = get_citation(pkg)
c = get_citation(pkg, badge=badge)
if !isnothing(c)
push!(pkg_citations, pkg.name=>c)
end
Expand Down Expand Up @@ -67,10 +78,12 @@ end
This function will create a .bib file with all the citations collected form
the CITATION.bib files corresponding to the dependecies of
the current active environment. Use `filename` to change the name of the
file. To include just the direct dependencies use `only_direct=true`
file. To include just the direct dependencies use `only_direct=true`.
Use `badge = true` to get the citations from packages without
a `Citation.bib` file, but with a DOI badge.
"""
function get_citations(;only_direct=false, filename="julia_citations.bib")
pkg_citations = collect_citations(only_direct)
function get_citations(;only_direct=false, filename="julia_citations.bib", badge=false)
pkg_citations = collect_citations(only_direct, badge=badge)

if isempty(pkg_citations)
@warn "No citations found in current environment"
Expand All @@ -80,3 +93,50 @@ function get_citations(;only_direct=false, filename="julia_citations.bib")

return nothing
end

"""
get_citation_badge(url::String)
This function will return an `OrderedDict` in the default to BibTeX format
from `Bibliography.jl`. The `url` argument is the link present in the DOI badge.
"""
function get_citation_badge(urlbadge)
isnothing(urlbadge) && return urlbadge

index_doi = findfirst("https://doi.org/", urlbadge)
if !isnothing(index_doi)
# If badge link is the doi
doi = urlbadge[index_doi[end]+1:end]
else
# If link is for `lastestdoi` in Zenodo
header = HTTP.head(urlbadge, redirect=false).headers
doi = last(header[findfirst(i -> isequal("Location", first(i)), header)])[17:end]
end
url = joinpath("https://data.datacite.org/", doi)
resp = HTTP.get(url, ["Accept"=>"application/x-bibtex"]; forwardheaders=true).body |> String
bib = parse_entry(resp)
return bib
end

"""
get_badge(pkg)
This function extracts the link in the DOI badge
present in the package's `README.md`.
"""
function get_badge(pkg)
readme_path = joinpath(pkg.source, "README.md")
if isfile(readme_path)
readme = open(f->read(f, String), readme_path)
getdoi = findfirst("![DOI]", readme)
if isnothing(getdoi)
urlbadge = nothing
else
index_init = findfirst('(', readme[getdoi[end]+3:end])[1]+getdoi[end]+3
index_final = findfirst(')',readme[index_init:end]) - 2
urlbadge = readme[index_init: index_init + index_final]
end
return urlbadge
end
return nothing
end
9 changes: 6 additions & 3 deletions src/tool_report.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ function make_sentence(pkg_citations; cite_commands=Dict{String,String}(), jl=tr
end

"""
get_tool_citation(io::IO=stdout; jl = true, texttt = false, copy = true, cite_commands=Dict{String,String}(), filename="julia_citations.bib")
get_tool_citation(io::IO=stdout; jl = true, texttt = false, copy = true, cite_commands=Dict{String,String}(), filename="julia_citations.bib"; badge=false)
Print a sentence describing the packages used in the current environment.
If you only want to consider the direct dependencies, you can set `only_direct=true`.
Expand All @@ -71,16 +71,19 @@ The package names have the .jl ending by default. You can ommit it with `jl=fals
Package names can be wrapped in `texttt` by setting `texttt=true` and you can also customize
the cite command used for each package by using `cite_commands=Dict("PackageName"=>"custom_cite")`.
The filename of the .bib file can be passed via the `filename` keyword.
Use `badge = true` to get the citations from packages without
a `Citation.bib` file, but with a DOI badge.
"""
function get_tool_citation(io::IO=stdout;
jl = true,
texttt = false,
copy = true,
only_direct = false,
cite_commands=Dict{String,String}(),
filename="julia_citations.bib")
filename="julia_citations.bib",
badge=false)

pkg_citations = collect_citations(only_direct)
pkg_citations = collect_citations(only_direct, badge=badge)

cite_sentence = make_sentence(pkg_citations; cite_commands, jl, texttt)
println(io, cite_sentence)
Expand Down
Loading

0 comments on commit e6bbf4e

Please sign in to comment.