Update doc to rst format for generation with Sphinx
This commit is contained in:
parent
6fc337095d
commit
ec97c0a320
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
__pycache__
|
__pycache__
|
||||||
|
docs/
|
||||||
|
13
database.py
13
database.py
@ -1,12 +1,23 @@
|
|||||||
"""
|
"""
|
||||||
This file contains the database schema in SQLAlchemy format.
|
This file contains the database schema in SQLAlchemy format.
|
||||||
"""
|
"""
|
||||||
from sqlalchemy import Column, Integer, String
|
from sqlalchemy import event, Column, Integer, String
|
||||||
|
from sqlalchemy.engine import Engine
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
|
@event.listens_for(Engine, "connect")
|
||||||
|
def set_sqlite_pragma(dbapi_connection, connection_record):
|
||||||
|
"""
|
||||||
|
Auto enable foreign keys for SQLite.
|
||||||
|
"""
|
||||||
|
cursor = dbapi_connection.cursor()
|
||||||
|
cursor.execute("PRAGMA foreign_keys=ON")
|
||||||
|
cursor.close()
|
||||||
|
|
||||||
|
|
||||||
class Paper(Base):
|
class Paper(Base):
|
||||||
__tablename__ = 'papers'
|
__tablename__ = 'papers'
|
||||||
id = Column(Integer, primary_key=True)
|
id = Column(Integer, primary_key=True)
|
||||||
|
11
main.py
11
main.py
@ -1,8 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import bottle
|
import bottle
|
||||||
from bottle.ext import sqlalchemy
|
from bottle.ext import sqlalchemy
|
||||||
from sqlalchemy import create_engine, event
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.engine import Engine
|
|
||||||
|
|
||||||
import database
|
import database
|
||||||
import routes
|
import routes
|
||||||
@ -32,14 +31,6 @@ plugin = sqlalchemy.Plugin(
|
|||||||
app.install(plugin)
|
app.install(plugin)
|
||||||
|
|
||||||
|
|
||||||
# Auto enable foreign keys for SQLite
|
|
||||||
@event.listens_for(Engine, "connect")
|
|
||||||
def set_sqlite_pragma(dbapi_connection, connection_record):
|
|
||||||
cursor = dbapi_connection.cursor()
|
|
||||||
cursor.execute("PRAGMA foreign_keys=ON")
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
|
|
||||||
# Routes
|
# Routes
|
||||||
app.get("/papers", callback=routes.get.fetch_papers)
|
app.get("/papers", callback=routes.get.fetch_papers)
|
||||||
app.get("/papers/<id:int>", callback=routes.get.fetch_by_id)
|
app.get("/papers/<id:int>", callback=routes.get.fetch_by_id)
|
||||||
|
@ -13,10 +13,8 @@ def sources_from_arxiv(eprint):
|
|||||||
"""
|
"""
|
||||||
Download sources on arXiv for a given preprint.
|
Download sources on arXiv for a given preprint.
|
||||||
|
|
||||||
Params:
|
:param eprint: The arXiv id (e.g. ``1401.2910`` or ``1401.2910v1``).
|
||||||
- eprint is the arXiv id (e.g. 1401.2910 or 1401.2910v1).
|
:returns: A ``TarFile`` object of the sources of the arXiv preprint.
|
||||||
|
|
||||||
Returns a TarFile object of the sources of the arXiv preprint.
|
|
||||||
"""
|
"""
|
||||||
r = requests.get("http://arxiv.org/e-print/%s" % (eprint,))
|
r = requests.get("http://arxiv.org/e-print/%s" % (eprint,))
|
||||||
file_object = io.BytesIO(r.content)
|
file_object = io.BytesIO(r.content)
|
||||||
@ -27,10 +25,8 @@ def bbl_from_arxiv(eprint):
|
|||||||
"""
|
"""
|
||||||
Get the .bbl files (if any) of a given preprint.
|
Get the .bbl files (if any) of a given preprint.
|
||||||
|
|
||||||
Params:
|
:param eprint: The arXiv id (e.g. ``1401.2910`` or ``1401.2910v1``).
|
||||||
- eprint is the arXiv id (e.g. 1401.2910 or 1401.2910v1).
|
:returns: A list of the ``.bbl`` files as text (if any) or ``None``.
|
||||||
|
|
||||||
Returns a list of the .bbl files as text (if any) or None.
|
|
||||||
"""
|
"""
|
||||||
tf = sources_from_arxiv(eprint)
|
tf = sources_from_arxiv(eprint)
|
||||||
bbl_files = [i for i in tf.getmembers() if i.name.endswith(".bbl")]
|
bbl_files = [i for i in tf.getmembers() if i.name.endswith(".bbl")]
|
||||||
@ -43,10 +39,8 @@ def get_cited_dois(eprint):
|
|||||||
"""
|
"""
|
||||||
Get the .bbl files (if any) of a given preprint.
|
Get the .bbl files (if any) of a given preprint.
|
||||||
|
|
||||||
Params:
|
:param eprint: The arXiv id (e.g. ``1401.2910`` or ``1401.2910v1``).
|
||||||
- eprint is the arXiv id (e.g. 1401.2910 or 1401.2910v1).
|
:returns: A dict of cleaned plaintext citations and their associated doi.
|
||||||
|
|
||||||
Returns a dict of cleaned plaintext citations and their associated doi.
|
|
||||||
"""
|
"""
|
||||||
bbl_files = bbl_from_arxiv(eprint)
|
bbl_files = bbl_from_arxiv(eprint)
|
||||||
dois = {}
|
dois = {}
|
||||||
@ -59,10 +53,8 @@ def get_arxiv_eprint_from_doi(doi):
|
|||||||
"""
|
"""
|
||||||
Get the arXiv eprint id for a given DOI.
|
Get the arXiv eprint id for a given DOI.
|
||||||
|
|
||||||
Params:
|
:param doi: The DOI of the resource to look for.
|
||||||
- doi is the DOI of the resource to look for.
|
:returns: The arXiv eprint id, or ``None`` if not found.
|
||||||
|
|
||||||
Returns the arXiv eprint id, or None if not found.
|
|
||||||
"""
|
"""
|
||||||
r = requests.get("http://export.arxiv.org/api/query",
|
r = requests.get("http://export.arxiv.org/api/query",
|
||||||
params={
|
params={
|
||||||
@ -80,10 +72,8 @@ def get_doi(eprint):
|
|||||||
"""
|
"""
|
||||||
Get the associated DOI for a given arXiv eprint.
|
Get the associated DOI for a given arXiv eprint.
|
||||||
|
|
||||||
Params:
|
:param eprint: The arXiv eprint id.
|
||||||
- eprint is the arXiv eprint id.
|
:returns: The DOI if any, or ``None``.
|
||||||
|
|
||||||
Returns the DOI if any, or None.
|
|
||||||
"""
|
"""
|
||||||
r = requests.get("http://export.arxiv.org/api/query",
|
r = requests.get("http://export.arxiv.org/api/query",
|
||||||
params={
|
params={
|
||||||
|
@ -13,12 +13,10 @@ from . import tools
|
|||||||
|
|
||||||
def clean_bibitem(bibitem):
|
def clean_bibitem(bibitem):
|
||||||
"""
|
"""
|
||||||
Return a plaintext representation of the bibitem from the bbl file.
|
Return a plaintext representation of the bibitem from the ``.bbl`` file.
|
||||||
|
|
||||||
Params:
|
:param bibitem: The text content of the bibitem.
|
||||||
- bibitem is the text content of the bibitem.
|
:returns: A cleaned plaintext citation from the bibitem.
|
||||||
|
|
||||||
Returns a cleaned plaintext citation from the bibitem.
|
|
||||||
"""
|
"""
|
||||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||||
output = subprocess.check_output(["%s/opendetex/delatex" % (script_dir,),
|
output = subprocess.check_output(["%s/opendetex/delatex" % (script_dir,),
|
||||||
@ -31,12 +29,11 @@ def clean_bibitem(bibitem):
|
|||||||
|
|
||||||
def parse(bbl):
|
def parse(bbl):
|
||||||
"""
|
"""
|
||||||
Parse a *.bbl file to get a clean list of plaintext citations.
|
Parse a ``*.bbl`` file to get a clean list of plaintext citations.
|
||||||
|
|
||||||
Params:
|
:param bbl: Either the path to the .bbl file or the content of a ``.bbl`` \
|
||||||
- bbl is either the path to the .bbl file or the content of a bbl file.
|
file.
|
||||||
|
:returns: A list of cleaned plaintext citations.
|
||||||
Returns a list of cleaned plaintext citations.
|
|
||||||
"""
|
"""
|
||||||
# Handle path or content
|
# Handle path or content
|
||||||
if os.path.isfile(bbl):
|
if os.path.isfile(bbl):
|
||||||
@ -59,11 +56,10 @@ def get_dois(bbl_input):
|
|||||||
"""
|
"""
|
||||||
Get the papers cited by the paper identified by the given DOI.
|
Get the papers cited by the paper identified by the given DOI.
|
||||||
|
|
||||||
Params:
|
:param bbl_input: Either the path to the .bbl file or the content of a \
|
||||||
- bbl_input is either the path to the .bbl file or the content of a bbl
|
bbl file.
|
||||||
file.
|
|
||||||
|
|
||||||
Returns a dict of cleaned plaintext citations and their associated doi.
|
:returns: A dict of cleaned plaintext citations and their associated doi.
|
||||||
"""
|
"""
|
||||||
cleaned_citations_with_URLs = parse(bbl_input)
|
cleaned_citations_with_URLs = parse(bbl_input)
|
||||||
dois = {}
|
dois = {}
|
||||||
|
@ -10,6 +10,9 @@ from . import tools
|
|||||||
def extract_doi_links(urls):
|
def extract_doi_links(urls):
|
||||||
"""
|
"""
|
||||||
Try to find a DOI from a given list of URLs.
|
Try to find a DOI from a given list of URLs.
|
||||||
|
|
||||||
|
:param urls: A list of URLs.
|
||||||
|
:returns: First matching DOI URL, or ``None``.
|
||||||
"""
|
"""
|
||||||
doi_urls = [url for url in urls if "/doi/" in url]
|
doi_urls = [url for url in urls if "/doi/" in url]
|
||||||
if len(doi_urls) > 0:
|
if len(doi_urls) > 0:
|
||||||
@ -22,6 +25,9 @@ def extract_doi_links(urls):
|
|||||||
def extract_arxiv_links(urls):
|
def extract_arxiv_links(urls):
|
||||||
"""
|
"""
|
||||||
Try to find an arXiv link from a given list of URLs.
|
Try to find an arXiv link from a given list of URLs.
|
||||||
|
|
||||||
|
:param urls: A list of URLs.
|
||||||
|
:returns: First matching arXiv URL, or ``None``.
|
||||||
"""
|
"""
|
||||||
arxiv_urls = [url for url in urls if "://arxiv.org" in url]
|
arxiv_urls = [url for url in urls if "://arxiv.org" in url]
|
||||||
if len(arxiv_urls) > 0:
|
if len(arxiv_urls) > 0:
|
||||||
@ -35,9 +41,14 @@ def match_doi_or_arxiv(text, only=["DOI", "arXiv"]):
|
|||||||
Search for a valid article ID (DOI or ArXiv) in the given text
|
Search for a valid article ID (DOI or ArXiv) in the given text
|
||||||
(regex-based).
|
(regex-based).
|
||||||
|
|
||||||
Returns a tuple (type, first matching ID) or None if not found.
|
From \
|
||||||
From : http://en.dogeno.us/2010/02/release-a-python-script-for-organizing-scientific-papers-pyrenamepdf-py/
|
http://en.dogeno.us/2010/02/release-a-python-script-for-organizing-scientific-papers-pyrenamepdf-py/ \
|
||||||
and https://github.com/minad/bibsync/blob/3fdf121016f6187a2fffc66a73cd33b45a20e55d/lib/bibsync/utils.rb
|
and \
|
||||||
|
https://github.com/minad/bibsync/blob/3fdf121016f6187a2fffc66a73cd33b45a20e55d/lib/bibsync/utils.rb.
|
||||||
|
|
||||||
|
:param text: Input text on which matching is to be done.
|
||||||
|
:param only: List of matches to look for (DOI/arXiv).
|
||||||
|
:returns: a tuple ``(type, first matching ID)`` or ``None`` if not found.
|
||||||
"""
|
"""
|
||||||
text = text.lower()
|
text = text.lower()
|
||||||
# Try to extract DOI
|
# Try to extract DOI
|
||||||
@ -86,10 +97,8 @@ def get_oa_version(doi):
|
|||||||
"""
|
"""
|
||||||
Get an OA version for a given DOI.
|
Get an OA version for a given DOI.
|
||||||
|
|
||||||
Params:
|
:param doi: A DOI or a dx.doi.org link.
|
||||||
- doi is a DOI or a dx.doi.org link.
|
:returns: The URL of the OA version of the given DOI, or ``None``.
|
||||||
|
|
||||||
Returns the URL of the OA version of the given DOI, or None.
|
|
||||||
"""
|
"""
|
||||||
# If DOI is a link, truncate it
|
# If DOI is a link, truncate it
|
||||||
if "dx.doi.org" in doi:
|
if "dx.doi.org" in doi:
|
||||||
|
@ -3,15 +3,17 @@ This file contains various utility functions.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def replaceAll(text, dic):
|
def replaceAll(text, replace_dict):
|
||||||
"""Replace all the dic keys by the associated item in text"""
|
"""
|
||||||
for i, j in dic.items():
|
Replace all the ``replace_dict`` keys by their associated item in ``text``.
|
||||||
|
"""
|
||||||
|
for i, j in replace_dict.items():
|
||||||
text = text.replace(i, j)
|
text = text.replace(i, j)
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
def clean_whitespaces(text):
|
def clean_whitespaces(text):
|
||||||
"""
|
"""
|
||||||
Remove double whitespaces and trailing . and , from text.
|
Remove double whitespaces and trailing "." and "," from text.
|
||||||
"""
|
"""
|
||||||
return ' '.join(text.strip().rstrip(".,").split())
|
return ' '.join(text.strip().rstrip(".,").split())
|
||||||
|
@ -11,15 +11,18 @@ def fetch_papers(db):
|
|||||||
"""
|
"""
|
||||||
Fetch all matching papers.
|
Fetch all matching papers.
|
||||||
|
|
||||||
```
|
.. code-block:: bash
|
||||||
|
|
||||||
GET /papers
|
GET /papers
|
||||||
Accept: application/vnd.api+json
|
Accept: application/vnd.api+json
|
||||||
```
|
|
||||||
|
|
||||||
Filtering is possible using `id=ID`, `doi=DOI`, `arxiv_id=ARXIV_ID` or any
|
|
||||||
combination of these GET parameters. Other parameters are ignored.
|
|
||||||
|
|
||||||
```
|
Filtering is possible using ``id=ID``, ``doi=DOI``, ``arxiv_id=ARXIV_ID`` \
|
||||||
|
or any combination of these GET parameters. Other parameters are ignored.
|
||||||
|
|
||||||
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
{
|
{
|
||||||
"data": [
|
"data": [
|
||||||
{
|
{
|
||||||
@ -38,7 +41,9 @@ def fetch_papers(db):
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
:param db: A database session, injected by the ``Bottle`` plugin.
|
||||||
|
:returns: An ``HTTPResponse``.
|
||||||
"""
|
"""
|
||||||
filters = {k: bottle.request.params[k]
|
filters = {k: bottle.request.params[k]
|
||||||
for k in bottle.request.params
|
for k in bottle.request.params
|
||||||
@ -55,12 +60,14 @@ def fetch_by_id(id, db):
|
|||||||
"""
|
"""
|
||||||
Fetch a resource identified by its internal id.
|
Fetch a resource identified by its internal id.
|
||||||
|
|
||||||
```
|
.. code-block:: bash
|
||||||
|
|
||||||
GET /id/<id>
|
GET /id/<id>
|
||||||
Accept: application/vnd.api+json
|
Accept: application/vnd.api+json
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
{
|
{
|
||||||
@ -79,7 +86,10 @@ def fetch_by_id(id, db):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
:param id: The id of the requested article.
|
||||||
|
:param db: A database session, injected by the ``Bottle`` plugin.
|
||||||
|
:returns: An ``HTTPResponse``.
|
||||||
"""
|
"""
|
||||||
resource = db.query(database.Paper).filter_by(id=id).first()
|
resource = db.query(database.Paper).filter_by(id=id).first()
|
||||||
if resource:
|
if resource:
|
||||||
|
@ -14,7 +14,8 @@ def create_paper(db):
|
|||||||
"""
|
"""
|
||||||
Create a new resource identified by its DOI or arXiv eprint id.
|
Create a new resource identified by its DOI or arXiv eprint id.
|
||||||
|
|
||||||
```
|
.. code-block:: bash
|
||||||
|
|
||||||
POST /papers
|
POST /papers
|
||||||
Content-Type: application/vnd.api+json
|
Content-Type: application/vnd.api+json
|
||||||
Accept: application/vnd.api+json
|
Accept: application/vnd.api+json
|
||||||
@ -26,9 +27,10 @@ def create_paper(db):
|
|||||||
"arxiv_id": "1401.2910"
|
"arxiv_id": "1401.2910"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
|
.. code-block:: json
|
||||||
|
|
||||||
{
|
{
|
||||||
"data": {
|
"data": {
|
||||||
{
|
{
|
||||||
@ -47,7 +49,9 @@ def create_paper(db):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
:param db: A database session, injected by the ``Bottle`` plugin.
|
||||||
|
:returns: An ``HTTPResponse``.
|
||||||
"""
|
"""
|
||||||
data = json.loads(bottle.request.body.read().decode("utf-8"))
|
data = json.loads(bottle.request.body.read().decode("utf-8"))
|
||||||
# Validate the request
|
# Validate the request
|
||||||
@ -83,7 +87,9 @@ def create_by_doi(doi, db):
|
|||||||
"""
|
"""
|
||||||
Create a new resource identified by its DOI, if it does not exist.
|
Create a new resource identified by its DOI, if it does not exist.
|
||||||
|
|
||||||
Return None if insertion failed, the Paper object otherwise.
|
:param doi: The DOI of the paper.
|
||||||
|
:param db: A database session.
|
||||||
|
:returns: ``None`` if insertion failed, the ``Paper`` object otherwise.
|
||||||
"""
|
"""
|
||||||
paper = database.Paper(doi=doi)
|
paper = database.Paper(doi=doi)
|
||||||
|
|
||||||
@ -110,7 +116,9 @@ def create_by_arxiv(arxiv, db):
|
|||||||
Create a new resource identified by its arXiv eprint ID, if it does not
|
Create a new resource identified by its arXiv eprint ID, if it does not
|
||||||
exist.
|
exist.
|
||||||
|
|
||||||
Return None if insertion failed, the Paper object otherwise.
|
:param arxiv: The arXiv eprint ID.
|
||||||
|
:param db: A database session.
|
||||||
|
:returns: ``None`` if insertion failed, the ``Paper`` object otherwise.
|
||||||
"""
|
"""
|
||||||
paper = database.Paper(arxiv_id=arxiv)
|
paper = database.Paper(arxiv_id=arxiv)
|
||||||
|
|
||||||
|
5
tools.py
5
tools.py
@ -7,7 +7,10 @@ import json
|
|||||||
|
|
||||||
def pretty_json(data):
|
def pretty_json(data):
|
||||||
"""
|
"""
|
||||||
Return pretty printed JSON-formatted string.
|
Return pretty-printed JSON-formatted string.
|
||||||
|
|
||||||
|
:param data: A string to be converted.
|
||||||
|
:returns: A pretty-printed JSON-formatted string.
|
||||||
"""
|
"""
|
||||||
return json.dumps(data,
|
return json.dumps(data,
|
||||||
sort_keys=True,
|
sort_keys=True,
|
||||||
|
Loading…
Reference in New Issue
Block a user